diff --git a/cps/editbooks.py b/cps/editbooks.py index d8e16e4c1..dd506fa6f 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -26,6 +26,7 @@ from datetime import datetime import json from shutil import copyfile from uuid import uuid4 +from markupsafe import escape try: from lxml.html.clean import clean_html except ImportError: @@ -468,7 +469,7 @@ def edit_book_comments(comments, book): comments = clean_html(comments) if len(book.comments): if book.comments[0].text != comments: - book.comments[0].text = clean_html(comments) + book.comments[0].text = comments modif_date = True else: if comments: @@ -663,9 +664,9 @@ def upload_single_file(request, book, book_id): return redirect(url_for('web.show_book', book_id=book.id)) # Queue uploader info - uploadText=_(u"File format %(ext)s added to %(book)s", ext=file_ext.upper(), book=book.title) - WorkerThread.add(current_user.name, TaskUpload( - "" + uploadText + "")) + link = '{}'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) + uploadText=_(u"File format %(ext)s added to %(book)s", ext=file_ext.upper(), book=link) + WorkerThread.add(current_user.name, TaskUpload(uploadText)) return uploader.process( saved_filename, *os.path.splitext(requested_file.filename), @@ -1038,9 +1039,9 @@ def upload(): gdriveutils.updateGdriveCalibreFromLocal() if error: flash(error, category="error") - uploadText=_(u"File %(file)s uploaded", file=title) - WorkerThread.add(current_user.name, TaskUpload( - "" + uploadText + "")) + link = '{}'.format(url_for('web.show_book', book_id=book_id), escape(title)) + uploadText = _(u"File %(file)s uploaded", file=link) + WorkerThread.add(current_user.name, TaskUpload(uploadText)) if len(request.files.getlist("btn-upload")) < 2: if current_user.role_edit() or current_user.role_admin(): diff --git a/cps/helper.py b/cps/helper.py index 860b5bf15..a78b7c21e 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -98,10 +98,10 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, settings['body'] = _(u'This e-mail has been sent via Calibre-Web.') else: settings = dict() - link = '{}"'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) # prevent xss + link = '{}'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) # prevent xss txt = u"{} -> {}: {}".format( - old_book_format, - new_book_format, + old_book_format.upper(), + new_book_format.upper(), link) settings['old_book_format'] = old_book_format settings['new_book_format'] = new_book_format @@ -216,9 +216,11 @@ def send_mail(book_id, book_format, convert, kindle_mail, calibrepath, user_id): for entry in iter(book.data): if entry.format.upper() == book_format.upper(): converted_file_name = entry.name + '.' + book_format.lower() + link = '{}'.format(url_for('web.show_book', book_id=book_id), escape(book.title)) + EmailText = _(u"%(book)s send to Kindle", book=link) WorkerThread.add(user_id, TaskEmail(_(u"Send to Kindle"), book.path, converted_file_name, config.get_mail_settings(), kindle_mail, - _(u"E-mail: %(book)s", book=book.title), _(u'This e-mail has been sent via Calibre-Web.'))) + EmailText, _(u'This e-mail has been sent via Calibre-Web.'))) return return _(u"The requested file could not be read. Maybe wrong permissions?") diff --git a/cps/services/gmail.py b/cps/services/gmail.py index 9380121a9..baada1f85 100644 --- a/cps/services/gmail.py +++ b/cps/services/gmail.py @@ -61,7 +61,7 @@ def get_user_info(credentials): return user_info.get('email', "") def send_messsage(token, msg): - log.debug("Start sending email via Gmail") + log.debug("Start sending e-mail via Gmail") creds = Credentials( token=token['token'], refresh_token=token['refresh_token'], @@ -80,4 +80,4 @@ def send_messsage(token, msg): body = {'raw': raw} (service.users().messages().send(userId='me', body=body).execute()) - log.debug("Email send successfully via Gmail") + log.debug("E-mail send successfully via Gmail") diff --git a/cps/static/js/table.js b/cps/static/js/table.js index b2a95bc93..a55ec5d13 100644 --- a/cps/static/js/table.js +++ b/cps/static/js/table.js @@ -36,10 +36,10 @@ $(function() { async: true, timeout: 900, success: function (data) { - $('#table').bootstrapTable("load", data); + $('#tasktable').bootstrapTable("load", data); } }); - }, 2000); + }, 1000); } $("#books-table").on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index 2e2a51d84..56cc7076d 100644 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -5,6 +5,7 @@ import re from glob import glob from shutil import copyfile +from markupsafe import escape from sqlalchemy.exc import SQLAlchemyError @@ -13,6 +14,7 @@ from cps import db from cps import logger, config from cps.subproc_wrapper import process_open from flask_babel import gettext as _ +from flask import url_for from cps.tasks.mail import TaskEmail from cps import gdriveutils @@ -24,6 +26,7 @@ class TaskConvert(CalibreTask): super(TaskConvert, self).__init__(taskMessage) self.file_path = file_path self.bookid = bookid + self.title = "" self.settings = settings self.kindle_mail = kindle_mail self.user = user @@ -35,6 +38,7 @@ class TaskConvert(CalibreTask): if config.config_use_google_drive: worker_db = db.CalibreDB(expire_on_commit=False) cur_book = worker_db.get_book(self.bookid) + self.title = cur_book.title data = worker_db.get_book_format(self.bookid, self.settings['old_book_format']) df = gdriveutils.getFileFromEbooksFolder(cur_book.path, data.name + "." + self.settings['old_book_format'].lower()) @@ -66,12 +70,13 @@ class TaskConvert(CalibreTask): # if we're sending to kindle after converting, create a one-off task and run it immediately # todo: figure out how to incorporate this into the progress try: + EmailText = _(u"%(book)s send to Kindle", book=escape(self.title)) worker_thread.add(self.user, TaskEmail(self.settings['subject'], self.results["path"], filename, self.settings, self.kindle_mail, - self.settings['subject'], + EmailText, self.settings['body'], internal=True) ) @@ -93,8 +98,9 @@ class TaskConvert(CalibreTask): local_db.get_book_format(self.bookid, self.settings['new_book_format']): log.info("Book id %d already converted to %s", book_id, format_new_ext) cur_book = local_db.get_book(book_id) + self.title = cur_book.title self.results['path'] = file_path - self.results['title'] = cur_book.title + self.results['title'] = self.title self._handleSuccess() local_db.session.close() return os.path.basename(file_path + format_new_ext) @@ -130,7 +136,8 @@ class TaskConvert(CalibreTask): local_db.session.close() return self.results['path'] = cur_book.path - self.results['title'] = cur_book.title + self.title = cur_book.title + self.results['title'] = self.title if not config.config_use_google_drive: self._handleSuccess() return os.path.basename(file_path + format_new_ext) diff --git a/cps/tasks/mail.py b/cps/tasks/mail.py index f19231ec8..292114d5a 100644 --- a/cps/tasks/mail.py +++ b/cps/tasks/mail.py @@ -143,7 +143,7 @@ class TaskEmail(CalibreTask): self.send_gmail_email(msg) except MemoryError as e: log.debug_or_exception(e) - self._handleError(u'MemoryError sending email: {}'.format(str(e))) + self._handleError(u'MemoryError sending e-mail: {}'.format(str(e))) except (smtplib.SMTPException, smtplib.SMTPAuthenticationError) as e: log.debug_or_exception(e) if hasattr(e, "smtp_error"): @@ -154,13 +154,13 @@ class TaskEmail(CalibreTask): text = '\n'.join(e.args) else: text = '' - self._handleError(u'Smtplib Error sending email: {}'.format(text)) + self._handleError(u'Smtplib Error sending e-mail: {}'.format(text)) except socket.error as e: log.debug_or_exception(e) - self._handleError(u'Socket Error sending email: {}'.format(e.strerror)) + self._handleError(u'Socket Error sending e-mail: {}'.format(e.strerror)) except Exception as ex: log.debug_or_exception(ex) - self._handleError(u'Error sending email: {}'.format(ex)) + self._handleError(u'Error sending e-mail: {}'.format(ex)) def send_standard_email(self, msg): @@ -173,7 +173,7 @@ class TaskEmail(CalibreTask): org_smtpstderr = smtplib.stderr smtplib.stderr = logger.StderrLogger('worker.smtp') - log.debug("Start sending email") + log.debug("Start sending e-mail") if use_ssl == 2: self.asyncSMTP = EmailSSL(self.settings["mail_server"], self.settings["mail_port"], timeout=timeout) @@ -196,7 +196,7 @@ class TaskEmail(CalibreTask): self.asyncSMTP.sendmail(self.settings["mail_from"], self.recipent, fp.getvalue()) self.asyncSMTP.quit() self._handleSuccess() - log.debug("Email send successfully") + log.debug("E-mail send successfully") if sys.version_info < (3, 0): smtplib.stderr = org_smtpstderr @@ -258,7 +258,7 @@ class TaskEmail(CalibreTask): @property def name(self): - return "Email" + return "E-mail" def __str__(self): return "{}, {}".format(self.name, self.subject) diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index 101769f70..5175c380d 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
Start Time: 2021-07-30 11:44:06
+Start Time: 2021-08-27 20:45:00
Stop Time: 2021-07-30 15:14:26
+Stop Time: 2021-08-28 00:16:11
Duration: 2h 45 min
+Duration: 2h 48 min
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 202, in test_convert_email + self.assertEqual(ret[-2]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 249, in test_convert_failed_and_email + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 337, in test_convert_only + self.assertEqual(ret_orig[-6]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 164, in test_convert_parameter + self.assertEqual(1, task_len) +AssertionError: 1 != 0+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 141, in test_convert_wrong_excecutable + self.assertEqual(2, task_len) +AssertionError: 2 != 0+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 457, in test_email_failed + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 416, in test_email_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 500, in test_ssl_smtp_setup_error + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 480, in test_starttls_smtp_setup_error + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 193, in test_convert_email
+ self.assertTrue("Email" in ret[-1]['task'])
+IndexError: list index out of range
+ Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 234, in test_convert_failed_and_email + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 324, in test_convert_only + self.assertEqual(ret[-6]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 157, in test_convert_parameter + self.assertEqual(task_len, 1) +AssertionError: 0 != 1+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 430, in test_email_failed + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 389, in test_email_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_kepubify.py", line 126, in test_convert_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_kepubify_gdrive.py", line 174, in test_convert_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/switch_to.py", line 82, in frame
+ frame_reference = self._driver.find_element(By.ID, frame_reference)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
+ return self.execute(Command.FIND_ELEMENT, {
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
+ self.error_handler.check_response(response)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
+ raise exception_class(message, screen, stacktrace)
+selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="description_ifr"]
-
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/switch_to.py", line 85, in frame
+ frame_reference = self._driver.find_element(By.NAME, frame_reference)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
+ return self.execute(Command.FIND_ELEMENT, {
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
+ self.error_handler.check_response(response)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
+ raise exception_class(message, screen, stacktrace)
+selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [name="description_ifr"]
+
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_edit_additional_books.py", line 673, in test_xss_comment_edit
+ self.edit_book(1, content={'description': ''})
+ File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 1608, in edit_book
+ cls.driver.switch_to.frame("description_ifr")
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/switch_to.py", line 87, in frame
+ raise NoSuchFrameException(frame_reference)
+selenium.common.exceptions.NoSuchFrameException: Message: description_ifr
+
+
+
+
+
+
+
+
+
+
+
+ TestEditAdditionalBooks - test_xss_custom_comment_edit
+
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_edit_additional_books.py", line 687, in test_xss_custom_comment_edit
+ self.edit_book(1, custom_content={'Custom Comment 人物': ''})
+ File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 1634, in edit_book
+ submit.click()
+AttributeError: 'bool' object has no attribute 'click'
+
+
+
+
+
+
+
+
+
+
+
TestEditBooks
35
- 34
- 0
+ 33
+ 1
0
1
@@ -859,11 +1291,32 @@
-
+
TestEditBooks - test_edit_comments
- PASS
+
+
+ FAIL
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_edit_books.py", line 428, in test_edit_comments
+ self.assertEqual('', values['comment'])
+AssertionError: '' != 'bogomirä 人物'
++ bogomirä 人物
+
+
+
+
+
@@ -1270,11 +1723,11 @@
-
+
TestEditBooksOnGdrive
20
- 20
- 0
+ 19
+ 1
0
0
@@ -1311,11 +1764,32 @@
-
+
TestEditBooksOnGdrive - test_edit_comments
- PASS
+
+
+ FAIL
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 639, in test_edit_comments
+ self.assertEqual('', values['comment'])
+AssertionError: '' != 'bogomirä 人物'
++ bogomirä 人物
+
+
+
+
+
@@ -1465,12 +1939,12 @@
-
+
TestSTARTTLS
3
- 3
- 0
+ 1
0
+ 2
0
Detail
@@ -1479,20 +1953,60 @@
-
+
TestSTARTTLS - test_STARTTLS
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_STARTTLS.py", line 79, in test_STARTTLS
+ self.assertEqual(ret[-1]['result'], 'Finished')
+IndexError: list index out of range
+
+
+
+
+
-
+
TestSTARTTLS - test_STARTTLS_SSL_setup_error
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_STARTTLS.py", line 100, in test_STARTTLS_SSL_setup_error
+ self.assertEqual(ret[-1]['result'], 'Failed')
+IndexError: list index out of range
+
+
+
+
+
@@ -1507,12 +2021,12 @@
-
+
TestSSL
6
- 6
- 0
+ 1
0
+ 5
0
Detail
@@ -1521,20 +2035,60 @@
-
+
TestSSL - test_SSL_None_setup_error
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 122, in test_SSL_None_setup_error
+ self.assertEqual('Failed', ret[-1]['result'])
+IndexError: list index out of range
+
+
+
+
+
-
+
TestSSL - test_SSL_STARTTLS_setup_error
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 101, in test_SSL_STARTTLS_setup_error
+ self.assertEqual(ret[-1]['result'], 'Failed')
+IndexError: list index out of range
+
+
+
+
+
@@ -1548,29 +2102,159 @@
-
+
TestSSL - test_SSL_non_admin_user
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 195, in test_SSL_non_admin_user
+ self.assertEqual(ret[-1]['result'], 'Finished')
+IndexError: list index out of range
+
+
+
+
+
-
+
TestSSL - test_SSL_only
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 64, in test_SSL_only
+ self.setup_server(False, {'mail_use_ssl': 'SSL/TLS'})
+ File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 674, in setup_server
+ select = Select(cls.driver.find_element_by_id(key))
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id
+ return self.find_element(by=By.ID, value=id_)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
+ return self.execute(Command.FIND_ELEMENT, {
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
+ self.error_handler.check_response(response)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
+ raise exception_class(message, screen, stacktrace)
+selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="mail_use_ssl"]
+
+
+
+
+
-
+
TestSSL - test_email_limit
- PASS
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 135, in test_email_limit
+ self.fill_basic_config({'config_uploading': 1})
+ File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 342, in fill_basic_config
+ cls._fill_basic_config(elements)
+ File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 252, in _fill_basic_config
+ WebDriverWait(cls.driver, 5).until(EC.presence_of_element_located((By.ID, "config_port")))
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/support/wait.py", line 80, in until
+ raise TimeoutException(message, screen, stacktrace)
+selenium.common.exceptions.TimeoutException: Message:
+
+
+
+
+
+
+
+
+
+
+
+ _ErrorHolder
+ 1
+ 0
+ 0
+ 1
+ 0
+
+ Detail
+
+
+
+
+
+
+
+ tearDownClass (test_email_ssl)
+
+
+
+ ERROR
+
+
+
+
+
+ Traceback (most recent call last):
+ File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 52, in tearDownClass
+ cls.stop_calibre_web()
+ File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 430, in stop_calibre_web
+ cls.driver.find_element_by_id('admin_stop').click()
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id
+ return self.find_element(by=By.ID, value=id_)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
+ return self.execute(Command.FIND_ELEMENT, {
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
+ self.error_handler.check_response(response)
+ File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
+ raise exception_class(message, screen, stacktrace)
+selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="admin_stop"]
+
+
+
+
+
@@ -1584,13 +2268,13 @@
0
0
- Detail
+ Detail