From 06a07ea28cfa72a19da5f3777c957237054f28f9 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 21 Oct 2020 15:43:21 +0200 Subject: [PATCH 01/11] [test/frontend] Fix broken editor references test --- test/frontend/test_editor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/frontend/test_editor.py b/test/frontend/test_editor.py index 10967b84..7fac422b 100644 --- a/test/frontend/test_editor.py +++ b/test/frontend/test_editor.py @@ -272,6 +272,8 @@ def test_add_references(self): driver.find_element_by_xpath('//*[@id="references-editor"]' '//input[contains(@class, "citation")]').send_keys("John, title.") + driver.find_element_by_xpath('//*[@id="references-editor"]' + '//input[contains(@class, "link")]').send_keys("123") driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() @@ -291,6 +293,8 @@ def test_add_references(self): driver.find_element_by_xpath('//*[@id="references-editor"]' '//input[contains(@class, "link")]').send_keys("www.link.com") + driver.find_element_by_xpath('//*[@id="references-editor"]' + '//input[contains(@class, "doi")]').send_keys("123") driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() From fb6af5779c4e9f6fc24590b6e04885b5ff431eb6 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 21 Oct 2020 16:26:18 +0200 Subject: [PATCH 02/11] [test/frontend] Rewrite readme --- test/frontend/Readme.md | 186 ++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 110 deletions(-) diff --git a/test/frontend/Readme.md b/test/frontend/Readme.md index c99ef2d1..9b6d3e42 100644 --- a/test/frontend/Readme.md +++ b/test/frontend/Readme.md @@ -1,55 +1,36 @@ Frontend Testing With Selenium ============================= -This file contains a description about the steps necessary in order to start testing with selenium -as well as some remarks about setting up new tests. +This file contains a description about necessary steps to start testing with selenium as well as some remarks about setting up new tests. -# Preliminary requirements -- Make sure that `activator test` has been run -- Make sure GCA-Web is running locally at the default port `9000` using `activator start` - -# Steps to Set Up Selenium - -Note this setup has been tested and used exclusively with Python 3.6. Using Python 2 is not +# Required Selenium setup +Note that this setup has been tested and used exclusively with Python 3.6. Using Python 2 is not encouraged. -Before the tests can run, several steps are needed in order for them to work. - -First of course, you need to install python-selenium, if you haven't done so already, -after setting up a virtual environment (not necessarily in this order): - -`pip install selenium pytest` - -Next, you need to get the drivers for the browsers your interested in, at the moment, -Google Chrome and Firefox are used. The drivers can be downloaded from this page: - -https://www.seleniumhq.org/download/ +- Download the Selenium server (`selenium-server-standalone-[version].jar`) from the [selenium page](https://www.seleniumhq.org/download) +- Information on how to get the webdrivers for Chrome and Firefox ("Geckodriver") can also be found on the page above. Since the location of these drivers has changed in the past, selenium does not link directly. The latest locations for driver downloads at this point where + - Firefox: [github](https://github.com/mozilla/geckodriver/releases) + - Chrome: [sites.google.com](https://sites.google.com/a/chromium.org/chromedriver) +- Make sure the server jar and the webdrivers are in a location that is available via the `PATH` environmental variable. +- Install the required python dependencies; `pip install selenium pytest`. +- Open a python shell and run the following code to check if the webdrivers work + + from selenium import webdriver + cdriver = webdriver.Chrome() + fdriver = webdriver.Firefox() -under "Third Party Drivers, Bindings, and Plugins". +- If any problems arise at this point, check whether the driver that was downloaded supports the actually installed corresponding browser. -Place them on your local machine and make sure they are available via the `PATH` environmental variable. - -Open a python shell and run the following code: - - from selenium import webdriver - cdriver = webdriver.Chrome() - fdriver = webdriver.Firefox() - -If any problems arise at this point, check whether the driver that was downloaded supports the -actually installed corresponding browser. +# Preliminary requirements -From the same source download the Selenium standalone server, something -along the lines of `selenium-server-standalone-[version].jar`, -and have it available. +## Test database setup +- Make sure that `activator test` has been run; all frontend tests depend on the the h2 test database content which is created when the backend tests are executed. +- Make sure GCA-Web is running locally at the default port `9000` using `activator run`. -To allow parallel and cross browser testing, and even giving the possibility of testing -with different operating systems and on different machines, we next set up selenium grid. -In order to do this, we need the selenium standalone server, which is already included as a java jar -in the "selenium" directory. Be sure to check out newer versions from time to time on the same page as above. -A hub is set up accessible via port 4444 by default, where nodes with different browsers can be added. +## Selenium preparation +To allow parallel and cross browser testing and even giving the possibility of testing with different operating systems and on different machines, we next set up selenium grid using the selenium server jar mentioned above. -The hub can be started by opening a terminal, changing to the selenium folder and then typing in the following command -(replace with you current version of the jar): +The hub can be started by opening a terminal, changing to the selenium folder and then typing in the following command (use your current version of the jar): ``` java -jar selenium-server-standalone-3.141.59.jar -role hub @@ -62,95 +43,80 @@ java -jar selenium-server-standalone-3.141.59.jar -role node ``` If you now visit [http://localhost:4444/grid/console](http://localhost:4444/grid/console/) you can see the node -registered and which browsers are available on each of them. -You can set the port, the browser running on the node and various other parameters. -It is also possible now to register nodes from different machines, given you know the IP of the hub, by expanding the -command above to +registered and which browsers are available on each of them. You can set the port, the browser running on the node and various other parameters. It is also possible now to register nodes from different machines, given you know the IP of the hub, by expanding the command above to ``` java -jar selenium-server-standalone-3.141.59.jar -role node -hub http://$IP of hub$:4444/grid/register ``` -Using just your local machine, you can also add more nodes via the same command, -speeding up the run time of the tests, as they will get distributed over these nodes by pytest. -For more helpful information about selenium grid, check out [the docs](https://www.seleniumhq.org/docs/07_selenium_grid.jsp) -and this [article on medium.com](https://medium.com/@arnonaxelrod/running-cross-browser-selenium-tests-in-parallel-using-selenium-grid-and-docker-containers-9ee293b86cfd) +You can also add more nodes via the same command, speeding up the run time of the tests, as they will get distributed over these nodes by `pytest`. -After this preparation, open yet another terminal. Before starting the tests, be sure to create a file containing -session cookies: +## Running the tests -``` -python load_cookies.py -``` +After the preparation steps above, open another terminal and navigate to the GCA-Web `test/frontend` folder. +The tests can be run by `python -m pytest` or `python -m pytest [testfile]`. -Now we can run the tests via the `pytest` or alternatively the `python -m pytest` command. Without any arguments, -all tests in the directory will be executed. -Specific tests can always be run by adding the file name to this command. -Using the `pytest-xdist` module, parallel testing is possible, decreasing the overall run time of the tests. Please note that `pytest-xdist` is an extension plugin, not part of the `pytest` distribution and needs to be installed separately. -Try to keep the number of open browser windows around 4-6, -otherwise the usage of memory space will increase times again. +Using the `pytest-xdist` module, parallel testing is possible, decreasing the overall run time of the tests. Please note that `pytest-xdist` is an extension plugin, not part of the `pytest` distribution and needs to be installed separately. Try to keep the number of open browser windows around 4-6, otherwise the usage of memory space will increase times again. -##Possible Problem Solutions +# Potential issues + +- Make sure that you browser and corresponding browser driver versions are compatible. This is likely the +cause behind errors of type + + selenium.common.exceptions.SessionNotCreatedException: Message: + Unable to create new service: ChromeDriverService -- Make absolutely sure that you browser and corresponding browser driver versions are compatible. This is likely the -cause behind errors of type: -``selenium.common.exceptions.SessionNotCreatedException: Message: Unable to create new service: ChromeDriverService`` - If you obtain a connection error in the browser, be sure that no proxy server is set in your browser. This might also cause the browser to load slowly. -# Creating New Tests +# Creating new tests There are some issues you can encounter, when adding tests. -Also there are many different ways to set up the frontend tests with selenium, unittest and pytest. - -Using `pytest` and fixtures, the unittest.TestCase class does not work. -For each class, you can add another fixture in the conftest.py file. -Driver set-up and starting at the login page is already contained in the `maximize_login(request)` function. -Working with the selenium standalone server, please set up new drivers via: - -```python -driver = webdriver.Remote( - command_executor="http://" + Cookies.get_host_ip() + ":4444/wd/hub", - desired_capabilities={'browserName': '$driver_name$', 'javascriptEnabled': True} - ) -``` +- Using `pytest` and fixtures, the `unittest.TestCase` class does not work. +- For each class, you can add another fixture in the `conftest.py` file. +- Driver set-up and starting at the login page is already contained in the `maximize_login(request)` function. +- Working with the selenium standalone server, set up new drivers via -In case, you want to run the tests without the standalone server, replace the remote webdriver. + ```python + driver = webdriver.Remote( + command_executor="http://" + Cookies.get_host_ip() + ":4444/wd/hub", + desired_capabilities={'browserName': '$driver_name$', 'javascriptEnabled': True} + ) + ``` -```python -driver = webdriver.Firefox() -#or -driver = webdriver.Chrome() -``` +- In case you want to run the tests without the standalone server, replace the remote webdriver. You only need to do this once in the `maximize_login(request)` function. -You only need to do this once in the `maximize_login(request)` function. - -If you want to add cookies, first open up another page, load the cookies and the go to the desired page or reload. -Compare with the already used set up functions in the conftest.py file. -An issue with selenium is that using `localhost` in URLs can cause problems with, e.g. loading cookies. -As a workaround, always use the `Cookies.get_host_ip()`. - -With most browser drivers, elements searched for by functions of the type ```driver.get_element_by_*()```, will be -found automatically, even if they're outside of the section currently viewed on the screen. In Firefox resp. with -Gecko driver, an error will be returned in such cases. It is important for Firefox to always navigate/scroll to the -element before examination by using ```move_to_element_by_*()```. For often used actions like ```click()```, -```send_keys()``` or ```get_attribute()``` functions including this are predefined in the conftest.py -file. - -Generally tests run stable. In some incidences a test might fail due to local issues, repeating the test might work -then. To avoid such problems, it is useful to include -```python -WebDriverWait(driver, 30).until( - # insert expected condition, e.g. - EC.presence_of_element_located((By.XPATH, '')) -) -``` -after processes that are expected to need some time to execute, e.g. when saving a form or loading a page or modal. + ```python + driver = webdriver.Firefox() + # or + driver = webdriver.Chrome() + ``` + +- If you want to add cookies, first open up another page, load the cookies and the go to the desired page or reload. Compare with the already used set up functions in the `conftest.py` file. An issue with selenium is that using `localhost` in URLs can cause problems with, e.g. loading cookies. As a workaround, always use the `Cookies.get_host_ip()`. + +- With most browser drivers, elements searched for by functions of the type `driver.get_element_by_*()` will be +found automatically, even if they're outside of the section currently viewed on the screen. In Firefox (Geckodriver) an error will be returned in such cases. It is important for Firefox to always navigate/scroll to the element before examination by using `move_to_element_by_*()`. For often used actions like the `click()`, `send_keys()` or `get_attribute()` functions including this are predefined in the `conftest.py` file. -For all things python and selenium, it's good to have a look at this page: +- Generally tests run stable. In some incidences a test might fail due to local issues, repeating the test might work then. To avoid such problems, it is useful to include the following code snipped after processes that are expected to need some time to execute, e.g. when saving a form or loading a page or modal. + + ```python + WebDriverWait(driver, 30).until( + # insert expected condition, e.g. + EC.presence_of_element_located((By.XPATH, '')) + ) + ``` + +# References and links + +- For all things python and selenium, it's good to have a look at this page https://selenium-python.readthedocs.io/ -A short tutorial for setting up selenium grid and creating a test class using unittest.TestCase instead of fixtures -can be found here: +- For more helpful information about selenium grid, check out the selenium documentation +https://www.selenium.dev/documentation/en/ + +- For information on selenium and docker, see [this article on medium.com](https://medium.com/@arnonaxelrod/running-cross-browser-selenium-tests-in-parallel-using-selenium-grid-and-docker-containers-9ee293b86cfd) + +- A short tutorial for setting up selenium grid and creating a test class using `unittest.TestCase` instead of fixtures can be found here https://gist.github.com/dzitkowskik/0fc641cf59af0dc3de62 + From 90ac3ca1df02b8de84c5d64d289c64410b544331 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 21 Oct 2020 16:59:26 +0200 Subject: [PATCH 03/11] [test/frontend/editor] Use helper method Use helper method to increase readability --- test/frontend/test_editor.py | 114 ++++++++++++++--------------------- 1 file changed, 45 insertions(+), 69 deletions(-) diff --git a/test/frontend/test_editor.py b/test/frontend/test_editor.py index 7fac422b..a9a71d11 100644 --- a/test/frontend/test_editor.py +++ b/test/frontend/test_editor.py @@ -8,15 +8,19 @@ @pytest.mark.usefixtures("setup_editor") class TestEditor: + def wait_until(self, delay, condition): + WebDriverWait(self.driver, delay).until(condition) + def click_edit_button(self, name): driver = self.driver if 'firefox' in driver.capabilities['browserName'] and name != 'title': move_to_element_by_class_name(driver, 'title') + move_to_element_by_class_name(driver, name) - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-' + name)) - ) - driver.find_element_by_id('button-edit-' + name).click() + + element_id = 'button-edit-' + name + self.wait_until(10, EC.visibility_of_element_located((By.ID, element_id))) + driver.find_element_by_id(element_id).click() def test_simple_creation(self): driver = self.driver @@ -31,9 +35,8 @@ def test_title(self): #wait for dialog to open #xpath neccessary, as several copies in source code - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="title-editor"]')) - ) + wait_on_path = '//*[@id="title-editor"]' + self.wait_until(30, EC.visibility_of_element_located((By.XPATH, wait_on_path))) #get title and set keys title = driver.find_element_by_xpath('//*[@id="title-editor"]//input[@id="title"]') @@ -43,15 +46,11 @@ def test_title(self): driver.find_element(By.XPATH, '//*[@id="title-editor"]//button[@id="modal-button-ok"]').click() #save - WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((By.ID, 'button-action')) - ) + self.wait_until(30, EC.element_to_be_clickable((By.ID, 'button-action'))) driver.find_element_by_id('button-action').click() #make sure, issues are shown - WebDriverWait(driver, 30).until( - EC.text_to_be_present_in_element((By.ID, 'lblvalid'), 'issues') - ) + self.wait_until(30, EC.text_to_be_present_in_element((By.ID, 'lblvalid'), 'issues')) #make sure, submit fails driver.find_element_by_id('button-action').click() @@ -63,9 +62,8 @@ def test_presentation_type(self): driver = self.driver self.click_edit_button('poster-or-talk') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="is-talk-editor"]')) - ) + wait_on_path = '//*[@id="is-talk-editor"]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="is-talk-editor"]//div[contains(@class, "radio")][2]//input').click() @@ -77,9 +75,8 @@ def test_add_author(self): driver = self.driver self.click_edit_button('authors') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="authors-editor"]//button[contains(@class, "btn-add")]').click() @@ -116,9 +113,8 @@ def test_remove_author(self): driver = self.driver self.click_edit_button('authors') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="authors-editor"]//tr[2]//button[contains(@class, "btn-remove")]').click() @@ -133,10 +129,8 @@ def test_add_affiliations(self): driver = self.driver self.click_edit_button('affiliations') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]').click() driver.find_element_by_xpath('//*[@id="affiliations-editor"]' @@ -158,10 +152,8 @@ def test_add_affiliations(self): self.click_edit_button('affiliations') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]').click() driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[4]' @@ -189,10 +181,8 @@ def test_remove_affiliations(self): driver = self.driver self.click_edit_button('affiliations') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "btn-remove")]')) - ) + wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-remove")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="affiliations-editor"]' '//tr[1]//button[contains(@class, "btn-remove")]').click() driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]').click() @@ -201,10 +191,9 @@ def test_remove_affiliations(self): assert len(driver.find_elements_by_xpath('//*[@class="affiliations"]//li[2]/span')) == 0 self.click_edit_button('affiliations') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "button-remove-affiliation-from-author")]')) - ) + + wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "button-remove-affiliation-from-author")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="affiliations-editor"]' '//button[contains(@class, "button-remove-affiliation-from-author")]').click() driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]').click() @@ -215,9 +204,8 @@ def test_text(self): driver = self.driver self.click_edit_button('abstract-text') - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]')) - ) + wait_on_path = '//*[@id="abstract-text-editor"]' + self.wait_until(30, EC.visibility_of_element_located((By.XPATH, wait_on_path))) text = driver.find_element_by_xpath('//*[@id="abstract-text-editor"]//textarea[@id="text"]') text.send_keys('Test abstract test.') @@ -229,9 +217,8 @@ def test_acknowledgements(self): driver = self.driver self.click_edit_button('acknowledgements') - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="acknowledgements-editor"]')) - ) + wait_on_path = '//*[@id="acknowledgements-editor"]' + self.wait_until(30, EC.visibility_of_element_located((By.XPATH, wait_on_path))) acknowledgements = driver.find_element_by_xpath('//*[@id="acknowledgements-editor"]' '//textarea[@id="acknowledgements"]') @@ -244,9 +231,8 @@ def test_add_references(self): driver = self.driver self.click_edit_button('references') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() driver.find_element_by_xpath('//*[@id="references-editor"]' @@ -263,12 +249,10 @@ def test_add_references(self): self.click_edit_button('references') - driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="references-editor"]' '//input[contains(@class, "citation")]').send_keys("John, title.") @@ -285,9 +269,8 @@ def test_add_references(self): self.click_edit_button('references') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() @@ -306,13 +289,11 @@ def test_add_references(self): self.click_edit_button('references') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) + wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() - driver.find_element_by_xpath('//*[@id="references-editor"]' '//input[contains(@class, "citation")]').send_keys("John, title.") driver.find_element_by_xpath('//*[@id="references-editor"]' @@ -322,20 +303,16 @@ def test_add_references(self): driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@class="references"]//a')) - ) - + wait_on_path = '//*[@class="references"]//a' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) assert len(driver.find_elements_by_xpath('//div[contains(@class, "callout")]/p')) == 0 def test_remove_references(self): driver = self.driver self.click_edit_button('references') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]' - '//button[contains(@class, "btn-remove")]')) - ) + wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-remove")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="references-editor"]//tr[1]' '//button[contains(@class, "btn-remove")]').click() @@ -348,9 +325,8 @@ def test_topic(self): driver = self.driver self.click_edit_button('topic') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) - ) + wait_on_path = '//*[@id="topic-editor"]//div[contains(@class, "radio")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) driver.find_element_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")][2]//input').click() From 3b019f22668bafaf96f6e7cf72f4b730a7dc3d4a Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 21 Oct 2020 18:53:58 +0200 Subject: [PATCH 04/11] [test/frontend/editor] Cleanup and description The file was refactored for readability and detailled descriptions were added to clarify which actions are taking place since the xpath strings make it hard to identify the current action. --- test/frontend/test_editor.py | 401 ++++++++++++++++++++++------------- 1 file changed, 251 insertions(+), 150 deletions(-) diff --git a/test/frontend/test_editor.py b/test/frontend/test_editor.py index a9a71d11..9de8239f 100644 --- a/test/frontend/test_editor.py +++ b/test/frontend/test_editor.py @@ -12,6 +12,11 @@ def wait_until(self, delay, condition): WebDriverWait(self.driver, delay).until(condition) def click_edit_button(self, name): + """ + Helper method to select and use specific modal edit button. + + :param name: id of the modal edit button + """ driver = self.driver if 'firefox' in driver.capabilities['browserName'] and name != 'title': move_to_element_by_class_name(driver, 'title') @@ -25,85 +30,106 @@ def click_edit_button(self, name): def test_simple_creation(self): driver = self.driver - #fail saving when empty abstract + # fail saving on an empty abstract driver.find_element_by_id('button-action').click() assert EC.visibility_of((By.XPATH, '/html/body/div[2]/div[2]/div[3]/div/h4')) def test_title(self): driver = self.driver + + # Open title modal self.click_edit_button('title') - #wait for dialog to open - #xpath neccessary, as several copies in source code + # Wait for modal to open; xpath is required since there are several copies + # in the source code wait_on_path = '//*[@id="title-editor"]' self.wait_until(30, EC.visibility_of_element_located((By.XPATH, wait_on_path))) - #get title and set keys + # Select title input field and set new value title = driver.find_element_by_xpath('//*[@id="title-editor"]//input[@id="title"]') title.send_keys('New Test Abstract') - #close modal - driver.find_element(By.XPATH, '//*[@id="title-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="title-editor"]//button[@id="modal-button-ok"]' + driver.find_element(By.XPATH, xpath_btn_modal).click() - #save + # Save abstract self.wait_until(30, EC.element_to_be_clickable((By.ID, 'button-action'))) driver.find_element_by_id('button-action').click() - #make sure, issues are shown + # Make sure that abstract issues are displayed self.wait_until(30, EC.text_to_be_present_in_element((By.ID, 'lblvalid'), 'issues')) - #make sure, submit fails + # Make sure that submit fails driver.find_element_by_id('button-action').click() - assert EC.text_to_be_present_in_element( - (By.XPATH, '/html/body/div[2]/div[2]/div[3]/div/p'), 'Unable to submit' - ) + + check_xpath = '/html/body/div[2]/div[2]/div[3]/div/p' + assert EC.text_to_be_present_in_element((By.XPATH, check_xpath), 'Unable to submit') def test_presentation_type(self): driver = self.driver + + # Open presentation type model self.click_edit_button('poster-or-talk') wait_on_path = '//*[@id="is-talk-editor"]' self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - driver.find_element_by_xpath('//*[@id="is-talk-editor"]//div[contains(@class, "radio")][2]//input').click() + # Test selecting 'Poster' as presentation type + xpath_radio = '//*[@id="is-talk-editor"]//div[contains(@class, "radio")][2]//input' + driver.find_element_by_xpath(xpath_radio).click() - driver.find_element_by_xpath('//*[@id="is-talk-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="is-talk-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Poster" in driver.find_element_by_xpath('//*[@class="poster-or-talk"]//span').text def test_add_author(self): driver = self.driver + + # Open authors modal self.click_edit_button('authors') - wait_on_path = '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + xpath_btn_add = '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_add))) + + # Test adding full author + driver.find_element_by_xpath(xpath_btn_add).click() + + xpath_fname = '//*[@id="authors-editor"]//input[contains(@class, "first-name")]' + xpath_mname = '//*[@id="authors-editor"]//input[contains(@class, "middle-name")]' + xpath_lname = '//*[@id="authors-editor"]//input[contains(@class, "last-name")]' + xpath_email = '//*[@id="authors-editor"]//input[contains(@class, "author-mail")]' + + driver.find_element_by_xpath(xpath_fname).send_keys("Alice") + driver.find_element_by_xpath(xpath_mname).send_keys("Bianca") + driver.find_element_by_xpath(xpath_lname).send_keys("Foo") + driver.find_element_by_xpath(xpath_email).send_keys("alice@example.com") + + # Test adding author, missing middle name + driver.find_element_by_xpath(xpath_btn_add).click() + + xpath_fname = '//*[@id="authors-editor"]//tr[2]//input[contains(@class, "first-name")]' + xpath_lname = '//*[@id="authors-editor"]//tr[2]//input[contains(@class, "last-name")]' + xpath_email = '//*[@id="authors-editor"]//tr[2]//input[contains(@class, "author-mail")]' + + driver.find_element_by_xpath(xpath_fname).send_keys("Bob") + driver.find_element_by_xpath(xpath_lname).send_keys("Bar") + driver.find_element_by_xpath(xpath_email).send_keys("bob@example.com") - driver.find_element_by_xpath('//*[@id="authors-editor"]//button[contains(@class, "btn-add")]').click() - - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//input[contains(@class, "first-name")]').send_keys("Alice") - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//input[contains(@class, "middle-name")]').send_keys("Bianca") - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//input[contains(@class, "last-name")]').send_keys("Foo") - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//input[contains(@class, "author-mail")]').send_keys("alice@example.com") - - driver.find_element_by_xpath('//*[@id="authors-editor"]//button[contains(@class, "btn-add")]').click() - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//tr[2]//input[contains(@class, "first-name")]').send_keys("Bob") - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//tr[2]//input[contains(@class, "last-name")]').send_keys("Bar") - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//tr[2]//input[contains(@class, "author-mail")]').send_keys("bob@example.com") - - driver.find_element_by_xpath('//*[@id="authors-editor"]//button[contains(@class, "btn-add")]').click() - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//tr[3]//input[contains(@class, "first-name")]').send_keys("Charlie") - driver.find_element_by_xpath('//*[@id="authors-editor"]' - '//tr[3]//input[contains(@class, "last-name")]').send_keys("Comma") - - driver.find_element_by_xpath('//*[@id="authors-editor"]//button[@id="modal-button-ok"]').click() + # Test adding author, missing email + driver.find_element_by_xpath(xpath_btn_add).click() + + xpath_fname = '//*[@id="authors-editor"]//tr[3]//input[contains(@class, "first-name")]' + xpath_lname = '//*[@id="authors-editor"]//tr[3]//input[contains(@class, "last-name")]' + + driver.find_element_by_xpath(xpath_fname).send_keys("Charlie") + driver.find_element_by_xpath(xpath_lname).send_keys("Comma") + + # Close modal + xpath_btn_modal = '//*[@id="authors-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Alice" in driver.find_element_by_xpath('//*[@class="authors"]//li[1]/span').text assert "Bob" in driver.find_element_by_xpath('//*[@class="authors"]//li[2]/span').text @@ -111,14 +137,20 @@ def test_add_author(self): def test_remove_author(self): driver = self.driver + + # Open authors modal self.click_edit_button('authors') wait_on_path = '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]' self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - driver.find_element_by_xpath('//*[@id="authors-editor"]//tr[2]//button[contains(@class, "btn-remove")]').click() + # Remove author + xpath_btn_rm = '//*[@id="authors-editor"]//tr[2]//button[contains(@class, "btn-remove")]' + driver.find_element_by_xpath(xpath_btn_rm).click() - driver.find_element_by_xpath('//*[@id="authors-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="authors-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Alice" in driver.find_element_by_xpath('//*[@class="authors"]//li[1]/span').text assert "Bob" not in driver.find_element_by_xpath('//*[@class="authors"]//li[2]/span').text @@ -127,223 +159,292 @@ def test_remove_author(self): def test_add_affiliations(self): driver = self.driver + + # Open affiliations modal self.click_edit_button('affiliations') - wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + xpath_btn_affil = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_affil))) + + # Add a full affiliation + driver.find_element_by_xpath(xpath_btn_affil).click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//input[contains(@class, "affil-department")]').send_keys("Bio") - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//input[contains(@class, "affil-institution")]').send_keys("University") - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//input[contains(@class, "affil-address")]').send_keys("Sesame Street 135a") - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//input[contains(@class, "affil-country")]').send_keys("Invenden") + xpath_dep = '//*[@id="affiliations-editor"]//input[contains(@class, "affil-department")]' + xpath_inst = '//*[@id="affiliations-editor"]//input[contains(@class, "affil-institution")]' + xpath_address = '//*[@id="affiliations-editor"]//input[contains(@class, "affil-address")]' + xpath_country = '//*[@id="affiliations-editor"]//input[contains(@class, "affil-country")]' + driver.find_element_by_xpath(xpath_dep).send_keys("Bio") + driver.find_element_by_xpath(xpath_inst).send_keys("University") + driver.find_element_by_xpath(xpath_address).send_keys("Sesame Street 135a") + driver.find_element_by_xpath(xpath_country).send_keys("Invenden") + + # Add affiliation to an author; select author from dropdown driver.find_element_by_xpath('//*[@id="affiliations-editor"]//select/option[1]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//button[@id="button-assign-affiliation-to-author"]').click() + # Add selected author + xpath_btn_asgn = '//*[@id="affiliations-editor"]//button[@id="button-assign-affiliation-to-author"]' + driver.find_element_by_xpath(xpath_btn_asgn).click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Bio" in driver.find_element_by_xpath('//*[@class="affiliations"]//li[1]/span').text + # Open affiliations modal self.click_edit_button('affiliations') - wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + xpath_btn_affil = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_affil))) + + # Add a new affiliation + driver.find_element_by_xpath(xpath_btn_affil).click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[contains(@class, "btn-add")]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[4]' - '//input[contains(@class, "affil-department")]').send_keys("Computational") - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[4]' - '//input[contains(@class, "affil-institution")]').send_keys("University") - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[4]' - '//input[contains(@class, "affil-address")]').send_keys("Long Street 1-3") - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[4]' - '//input[contains(@class, "affil-country")]').send_keys("Fantidan") + xpath_dep = '//*[@id="affiliations-editor"]//tr[4]//input[contains(@class, "affil-department")]' + xpath_inst = '//*[@id="affiliations-editor"]//tr[4]//input[contains(@class, "affil-institution")]' + xpath_address = '//*[@id="affiliations-editor"]//tr[4]//input[contains(@class, "affil-address")]' + xpath_country = '//*[@id="affiliations-editor"]//tr[4]//input[contains(@class, "affil-country")]' + driver.find_element_by_xpath(xpath_dep).send_keys("Computational") + driver.find_element_by_xpath(xpath_inst).send_keys("University") + driver.find_element_by_xpath(xpath_address).send_keys("Long Street 1-3") + driver.find_element_by_xpath(xpath_country).send_keys("Fantidan") + + xpath_btn_asgn = '//*[@id="affiliations-editor"]//tr[6]//button[@id="button-assign-affiliation-to-author"]' + # Assign author one driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[6]//select/option[1]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[6]' - '//button[@id="button-assign-affiliation-to-author"]').click() + driver.find_element_by_xpath(xpath_btn_asgn).click() + # Assign author two driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[6]//select/option[2]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//tr[6]' - '//button[@id="button-assign-affiliation-to-author"]').click() + driver.find_element_by_xpath(xpath_btn_asgn).click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Computational" in driver.find_element_by_xpath('//*[@class="affiliations"]//li[2]/span').text def test_remove_affiliations(self): driver = self.driver + + # Open affiliations modal self.click_edit_button('affiliations') - wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "btn-remove")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//tr[1]//button[contains(@class, "btn-remove")]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]').click() + xpath_btn_rm = '//*[@id="affiliations-editor"]//tr[1]//button[contains(@class, "btn-remove")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_rm))) + + # Remove affiliation + driver.find_element_by_xpath(xpath_btn_rm).click() + + # Close modal + xpath_btn_modal = '//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Bio" not in driver.find_element_by_xpath('//*[@class="affiliations"]//li[1]/span').text assert len(driver.find_elements_by_xpath('//*[@class="affiliations"]//li[2]/span')) == 0 + # Open affiliations modal self.click_edit_button('affiliations') - wait_on_path = '//*[@id="affiliations-editor"]//button[contains(@class, "button-remove-affiliation-from-author")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - driver.find_element_by_xpath('//*[@id="affiliations-editor"]' - '//button[contains(@class, "button-remove-affiliation-from-author")]').click() - driver.find_element_by_xpath('//*[@id="affiliations-editor"]//button[@id="modal-button-ok"]').click() + # Remove author from affiliation + xpath_btn_author = '//*[@id="affiliations-editor"]' \ + '//button[contains(@class, "button-remove-affiliation-from-author")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_author))) + driver.find_element_by_xpath(xpath_btn_author).click() + + # Close modal + driver.find_element_by_xpath(xpath_btn_modal).click() assert "Computational" in driver.find_element_by_xpath('//*[@class="affiliations"]//li[1]/span').text def test_text(self): driver = self.driver + + # Open abstracts text modal self.click_edit_button('abstract-text') wait_on_path = '//*[@id="abstract-text-editor"]' self.wait_until(30, EC.visibility_of_element_located((By.XPATH, wait_on_path))) + # Add abstract text value + test_content = "Test abstract test." text = driver.find_element_by_xpath('//*[@id="abstract-text-editor"]//textarea[@id="text"]') - text.send_keys('Test abstract test.') - driver.find_element(By.XPATH, '//*[@id="abstract-text-editor"]//button[@id="modal-button-ok"]').click() + text.send_keys(test_content) + + # Close modal + xpath_btn_modal = '//*[@id="abstract-text-editor"]//button[@id="modal-button-ok"]' + driver.find_element(By.XPATH, xpath_btn_modal).click() - assert "Test abstract test." in driver.find_element_by_xpath('//*[@class="abstract-text"]/p').text + assert test_content in driver.find_element_by_xpath('//*[@class="abstract-text"]/p').text def test_acknowledgements(self): driver = self.driver + + # Open acknowledgements modal self.click_edit_button('acknowledgements') wait_on_path = '//*[@id="acknowledgements-editor"]' self.wait_until(30, EC.visibility_of_element_located((By.XPATH, wait_on_path))) - acknowledgements = driver.find_element_by_xpath('//*[@id="acknowledgements-editor"]' - '//textarea[@id="acknowledgements"]') - acknowledgements.send_keys('Thanks.') - driver.find_element(By.XPATH, '//*[@id="acknowledgements-editor"]//button[@id="modal-button-ok"]').click() + # Add acknowledgements value + test_content = "Thanks." + xpath_ack = '//*[@id="acknowledgements-editor"]//textarea[@id="acknowledgements"]' + acknowledgements = driver.find_element_by_xpath(xpath_ack) + acknowledgements.send_keys(test_content) - assert "Thanks." in driver.find_element_by_xpath('//*[@class="acknowledgements"]/p').text + # Close modal + xpath_btn_modal = '//*[@id="acknowledgements-editor"]//button[@id="modal-button-ok"]' + driver.find_element(By.XPATH, xpath_btn_modal).click() + + assert test_content in driver.find_element_by_xpath('//*[@class="acknowledgements"]/p').text def test_add_references(self): driver = self.driver + + # Open references modal self.click_edit_button('references') - wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + xpath_btn_add_ref = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_add_ref))) - driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "citation")]').send_keys("5657") + xpath_citation = '//*[@id="references-editor"]//input[contains(@class, "citation")]' + xpath_link = '//*[@id="references-editor"]//input[contains(@class, "link")]' + xpath_doi = '//*[@id="references-editor"]//input[contains(@class, "doi")]' - driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() + # Test invalid reference citation + driver.find_element_by_xpath(xpath_btn_add_ref).click() + driver.find_element_by_xpath(xpath_citation).send_keys("5657") - #assert driver.find_element_by_xpath('//*[@class="references"]//a') + # Close modal + xpath_btn_modal = '//*[@id="references-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() + + # Check an error callout is displayed assert driver.find_element_by_xpath('//div[contains(@class, "callout")]/p') - assert EC.text_to_be_present_in_element( - (By.XPATH, '//div[contains(@class, "callout")]/p'), 'Reference text' - ) + # Check correct error message + test_msg = "Reference citation" + assert EC.text_to_be_present_in_element((By.XPATH, '//div[contains(@class, "callout")]/p'), test_msg) + # Open references modal self.click_edit_button('references') - driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() - - wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + # Test invalid reference link + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_add_ref))) + driver.find_element_by_xpath(xpath_btn_add_ref).click() - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "citation")]').send_keys("John, title.") - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "link")]').send_keys("123") + # Add valid reference citation value + driver.find_element_by_xpath(xpath_citation).send_keys("John, title.") + # Add invalid reference link value + driver.find_element_by_xpath(xpath_link).send_keys("123") - driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="references-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() + # Check an error callout is displayed assert driver.find_element_by_xpath('//div[contains(@class, "callout")]/p') - assert EC.text_to_be_present_in_element( - (By.XPATH, '//div[contains(@class, "callout")]/p'), 'Reference link' - ) + # Check correct error message + test_msg = "Reference link" + assert EC.text_to_be_present_in_element((By.XPATH, '//div[contains(@class, "callout")]/p'), test_msg) + # Open references modal self.click_edit_button('references') - wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - - driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() + # Test invalid reference doi + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_add_ref))) + driver.find_element_by_xpath(xpath_btn_add_ref).click() - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "link")]').send_keys("www.link.com") - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "doi")]').send_keys("123") + # Add valid reference link value + driver.find_element_by_xpath(xpath_link).send_keys("www.link.com") + # Add invalid reference doi value + driver.find_element_by_xpath(xpath_doi).send_keys("123") - driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + driver.find_element_by_xpath(xpath_btn_modal).click() + # Check an error callout is displayed assert driver.find_element_by_xpath('//div[contains(@class, "callout")]/p') - assert EC.text_to_be_present_in_element( - (By.XPATH, '//div[contains(@class, "callout")]/p'), 'Reference doi' - ) + # Check correct error message + test_msg = "Reference doi" + assert EC.text_to_be_present_in_element((By.XPATH, '//div[contains(@class, "callout")]/p'), test_msg) + # Open references modal self.click_edit_button('references') - wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-add")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - - driver.find_element_by_xpath('//*[@id="references-editor"]//button[contains(@class, "btn-add")]').click() + # Test valid reference entry + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_add_ref))) + driver.find_element_by_xpath(xpath_btn_add_ref).click() - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "citation")]').send_keys("John, title.") - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "link")]').send_keys("www.link.com") - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "doi")]').send_keys("doi:0000000/000000000000") + driver.find_element_by_xpath(xpath_citation).send_keys("John, title.") + driver.find_element_by_xpath(xpath_link).send_keys("www.link.com") + driver.find_element_by_xpath(xpath_doi).send_keys("doi:0000000/000000000000") - driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + driver.find_element_by_xpath(xpath_btn_modal).click() wait_on_path = '//*[@class="references"]//a' self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + + # Check absence of error callout assert len(driver.find_elements_by_xpath('//div[contains(@class, "callout")]/p')) == 0 def test_remove_references(self): driver = self.driver + + # Open references modal self.click_edit_button('references') - wait_on_path = '//*[@id="references-editor"]//button[contains(@class, "btn-remove")]' - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) + xpath_btn_rm = '//*[@id="references-editor"]//tr[1]//button[contains(@class, "btn-remove")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_btn_rm))) - driver.find_element_by_xpath('//*[@id="references-editor"]//tr[1]' - '//button[contains(@class, "btn-remove")]').click() + # Remove reference + driver.find_element_by_xpath(xpath_btn_rm).click() - driver.find_element_by_xpath('//*[@id="references-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="references-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() + # Check absence of error callout assert len(driver.find_elements_by_xpath('//*[@class="references"]//a')) == 0 def test_topic(self): driver = self.driver + + # Open topic modal self.click_edit_button('topic') wait_on_path = '//*[@id="topic-editor"]//div[contains(@class, "radio")]' self.wait_until(10, EC.element_to_be_clickable((By.XPATH, wait_on_path))) - driver.find_element_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")][2]//input').click() + # Select topic + xpath_radio = '//*[@id="topic-editor"]//div[contains(@class, "radio")][2]//input' + driver.find_element_by_xpath(xpath_radio).click() - driver.find_element_by_xpath('//*[@id="topic-editor"]//button[@id="modal-button-ok"]').click() + # Close modal + xpath_btn_modal = '//*[@id="topic-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_btn_modal).click() assert "topic two" in driver.find_element_by_xpath('//*[@class="topic"]/p').text def test_submit(self): driver = self.driver + + # Submit abstract driver.find_element_by_id('button-action').click() - assert EC.text_to_be_present_in_element( - (By.XPATH, '//*[@class_name="label-primary"]'), 'Submitted' - ) + + # Check abstract status + test_status = "Submitted" + assert EC.text_to_be_present_in_element((By.XPATH, '//*[@class_name="label-primary"]'), test_status) def test_unlock(self): driver = self.driver + + # Unlock submitted abstract driver.find_element_by_id('button-action').click() - assert EC.text_to_be_present_in_element( - (By.XPATH, '//*[@class_name="label-primary"]'), 'InPreparation' - ) + + # Check abstract status + test_status = "InPreparation" + assert EC.text_to_be_present_in_element((By.XPATH, '//*[@class_name="label-primary"]'), test_status) From cc248e07a23d0f7ddc5fb80371d8e2b825761bbe Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 21 Oct 2020 19:01:38 +0200 Subject: [PATCH 05/11] [test/frontend/login] Cleanup and description --- test/frontend/test_login.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/test/frontend/test_login.py b/test/frontend/test_login.py index 8d308ed0..d00f5cc8 100644 --- a/test/frontend/test_login.py +++ b/test/frontend/test_login.py @@ -8,35 +8,41 @@ @pytest.mark.usefixtures("setup_login") class TestLogin: + def wait_until(self, delay, condition): + WebDriverWait(self.driver, delay).until(condition) + def test_login(self, user="alice@foo.com", password="testtest"): driver = self.driver + + # Test invalid username driver.find_element_by_id("identifier").send_keys("wrong_alice") driver.find_element_by_id("password").send_keys(password) driver.find_element_by_id("submit").click() - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, "password")) - ) + # Presence of the 'password' element implies a failed login + self.wait_until(30, EC.presence_of_element_located((By.ID, "password"))) + + # Test invalid password driver.find_element_by_id("identifier").send_keys(user) driver.find_element_by_id("password").send_keys("wrong_password") driver.find_element_by_id("submit").click() - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, "password")) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, "password"))) + + # Test valid login driver.find_element_by_id("identifier").send_keys(user) driver.find_element_by_id("password").send_keys(password) driver.find_element_by_id("submit").click() - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, "usermenu")) - ) + + # Presence of the 'usermenu' element implies successful login + self.wait_until(30, EC.presence_of_element_located((By.ID, "usermenu"))) def test_logout(self): driver = self.driver + driver.get("http://" + Cookies.get_host_ip() + ":9000/conferences") - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="usermenu"]')) - ) + self.wait_until(30, EC.visibility_of_element_located((By.XPATH, '//*[@id="usermenu"]'))) + driver.find_element_by_id("usermenu").click() driver.find_element_by_partial_link_text("Logout").click() assert driver.find_element_by_partial_link_text("Login") From c2138798170523d7b8d65f3de1cf51c7b044df92 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 21 Oct 2020 19:28:17 +0200 Subject: [PATCH 06/11] [test/frontend/conferences] Use helper method --- test/frontend/test_conference_creation.py | 162 ++++++++-------------- 1 file changed, 58 insertions(+), 104 deletions(-) diff --git a/test/frontend/test_conference_creation.py b/test/frontend/test_conference_creation.py index ef310c73..954b133d 100644 --- a/test/frontend/test_conference_creation.py +++ b/test/frontend/test_conference_creation.py @@ -13,6 +13,9 @@ @pytest.mark.usefixtures("setup_conference_creation") class TestConferenceCreation: + def wait_until(self, delay, condition): + WebDriverWait(self.driver, delay).until(condition) + def test_name(self): driver = self.driver element_send_keys_by_id(driver, 'name', "Test Conference") @@ -30,20 +33,17 @@ def test_short(self): element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.XPATH, '//div[contains(@class,"alert-danger")]/strong')) - ) + xpath_alert = '//div[contains(@class,"alert-danger")]/strong' + self.wait_until(30, EC.presence_of_element_located((By.XPATH, xpath_alert))) assert "Conference short is already in use." in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + driver.find_element_by_xpath(xpath_alert).text element_send_keys_by_id(driver, 'short', tc_num) element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.invisibility_of_element_located((By.XPATH, '//div[contains(@class,"alert-danger")]/strong')) - ) - assert len(driver.find_elements_by_xpath('//div[contains(@class,"alert-danger")]/strong')) == 0 + self.wait_until(30, EC.invisibility_of_element_located((By.XPATH, xpath_alert))) + assert len(driver.find_elements_by_xpath(xpath_alert)) == 0 #move to front page and check, whether conference is shown and marked as "Unpublished" driver.get("http://" + Cookies.get_host_ip() + ":9000/") @@ -60,9 +60,8 @@ def test_short(self): def test_published(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'published')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'published'))) element_click_by_id(driver, 'published') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -82,9 +81,8 @@ def test_published(self): # thumbnail only shown if conference not active def test_thumbnail_url(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'thumbnail')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'thumbnail'))) element_send_keys_by_id(driver, 'thumbnail', 'https://portal.g-node.org/abstracts/bc14/BC14_icon.png') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -101,9 +99,7 @@ def test_thumbnail_url(self): def test_active(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'active')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'active'))) element_click_by_id(driver, 'active') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -124,9 +120,7 @@ def test_active(self): def test_submission(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'short')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'short'))) tc_num = element_get_attribute_by_id(driver, 'short', 'value') driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) @@ -136,9 +130,7 @@ def test_submission(self): element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'submission')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'submission'))) element_click_by_id(driver, 'submission') element_click_by_class_name(driver, 'btn-success') @@ -153,9 +145,8 @@ def test_submission(self): def test_group(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'group')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'group'))) element_send_keys_by_id(driver, 'group', 'Test Group 1') def test_cite(self): @@ -166,9 +157,8 @@ def test_cite(self): def test_start_date(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'start')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'start'))) element_click_by_id(driver, 'start') move_to_element_by_id(driver, 'ui-datepicker-div') @@ -179,9 +169,7 @@ def test_start_date(self): element_click_by_class_name(driver, 'btn-success') # other elements might not be reachable immediately after click of "Save" button - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'start')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'start'))) assert "14" in element_get_attribute_by_xpath(driver, '//*[@id="start"]', 'value') old_date = element_get_attribute_by_id(driver, 'start', 'value') @@ -208,9 +196,8 @@ def test_start_date(self): def test_end_date(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'end')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'end'))) element_click_by_id(driver, 'end') move_to_element_by_id(driver, 'ui-datepicker-div') @@ -221,9 +208,7 @@ def test_end_date(self): element_click_by_class_name(driver, 'btn-success') # other elements might not be reachable immediately after click of "Save" button - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'end')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'end'))) assert "16" in element_get_attribute_by_xpath(driver, '//*[@id="end"]', 'value') old_date = element_get_attribute_by_id(driver, 'end', 'value') @@ -250,9 +235,8 @@ def test_end_date(self): def test_deadline(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'deadline')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'deadline'))) element_click_by_id(driver, 'deadline') driver.find_element_by_id('deadline').click() @@ -263,9 +247,7 @@ def test_deadline(self): element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'deadline')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'deadline'))) assert "10" in element_get_attribute_by_xpath(driver, '//*[@id="deadline"]', 'value') old_date = element_get_attribute_by_id(driver, 'deadline', 'value') @@ -280,9 +262,8 @@ def test_deadline(self): def test_logo_url(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'logo')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'logo'))) element_send_keys_by_id(driver, 'logo', 'https://portal.g-node.org/abstracts/bc18/BC18_header.jpg') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -300,9 +281,8 @@ def test_logo_url(self): def test_iosapp(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'iosapp')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'iosapp'))) element_send_keys_by_id(driver, 'iosapp', '999999999') def test_link(self): @@ -322,9 +302,8 @@ def test_link(self): def test_description(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'desc')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'desc'))) element_send_keys_by_id(driver, 'desc', 'Important conference.') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -341,9 +320,8 @@ def test_description(self): def test_notice(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'notice')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'notice'))) element_send_keys_by_id(driver, 'notice', 'Check abstracts before submission!') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -357,9 +335,8 @@ def test_notice(self): def test_presentation_preferences(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'presentation')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'presentation'))) element_click_by_id(driver, 'presentation') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -374,9 +351,8 @@ def test_presentation_preferences(self): def test_add_topic(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'addTopic')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'addTopic'))) element_send_keys_by_id(driver, 'addTopic', 'Topic 1') driver.find_element_by_id('btn-add-topic').click() @@ -394,14 +370,11 @@ def test_add_topic(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") move_to_element_by_class_name(driver, 'topic') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-topic')) - ) + + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-topic'))) driver.find_element_by_id('button-edit-topic').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) - ) + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]'))) assert len(driver.find_elements_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")]//input')) == 2 @@ -413,10 +386,8 @@ def test_add_topic(self): def test_remove_topic(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'addTopic')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'addTopic'))) move_to_element_by_xpath(driver, '//ul/li/span[contains(text(),"Topic 1")]/../a') driver.find_element_by_xpath('//ul/li/span[contains(text(),"Topic 1")]/../a').click() @@ -429,14 +400,10 @@ def test_remove_topic(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") move_to_element_by_class_name(driver, 'topic') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-topic')) - ) + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-topic'))) driver.find_element_by_id('button-edit-topic').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) - ) + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]'))) assert len(driver.find_elements_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")]//input')) == 1 assert "Topic 2" in driver.find_element_by_xpath('//*[@id="topic-editor"]' @@ -449,9 +416,8 @@ def test_remove_topic(self): def test_maximum_abstract_length(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mAbsLen')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'mAbsLen'))) # initial mAbsLen = 2000 element_send_keys_by_id(driver, 'mAbsLen', '300') @@ -461,9 +427,7 @@ def test_maximum_abstract_length(self): element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mAbsLen')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'mAbsLen'))) move_to_element_by_id(driver, 'mAbsLen') assert "300" == driver.find_element_by_id('mAbsLen').get_attribute('value') @@ -472,14 +436,11 @@ def test_maximum_abstract_length(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") move_to_element_by_class_name(driver, 'abstract-text') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text')) - ) + + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text'))) driver.find_element_by_id('button-edit-abstract-text').click() - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]')) - ) + self.wait_until(30, EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]'))) assert driver.find_element_by_xpath('//*[@id="abstract-text-editor"]' '//textarea[@id="text"]').get_attribute("maxlength") == '300' @@ -490,16 +451,14 @@ def test_maximum_abstract_length(self): def test_maximum_figures(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mFigs')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.ID, 'mFigs'))) element_send_keys_by_id(driver, 'mFigs', '3') element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mFigs')) - ) + self.wait_until(30, EC.presence_of_element_located((By.ID, 'mFigs'))) + move_to_element_by_id(driver, 'mFigs') assert "3" == driver.find_element_by_id('mFigs').get_attribute('value') @@ -509,14 +468,10 @@ def test_maximum_figures(self): move_to_element_by_class_name(driver, 'figure') assert len(driver.find_elements_by_class_name('figure')) == 1 - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-figure')) - ) + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-figure'))) driver.find_element_by_id('button-edit-figure').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]')) - ) + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]'))) assert len(driver.find_elements_by_xpath('//*[@id="figures-editor"]//div[@class="modal-body"]' '//div[contains(@data-bind, "figures().length>=3")]')) == 1 @@ -528,9 +483,8 @@ def test_maximum_figures(self): def test_groups(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.XPATH, '//li/a[contains(@href,"groups")]')) - ) + + self.wait_until(30, EC.presence_of_element_located((By.XPATH, '//li/a[contains(@href,"groups")]'))) move_to_element_by_xpath(driver, '//li/a[contains(@href,"groups")]') driver.find_element_by_xpath('//li/a[contains(@href,"groups")]').click() From 0f47e0e20ac6ffe184aa7dedd96982212ee95d0b Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 28 Oct 2020 09:42:49 +0100 Subject: [PATCH 07/11] [test/frontend/conferences] Test issue fix Switching between conference settings, start page and abstract and returning to conference settings via xpath lead to access of other conferences than the intended leading to seemingly random test fails. Changing the access method of the conference settings page fixed all test fails. --- test/frontend/test_conference_creation.py | 215 ++++++++++++++-------- 1 file changed, 140 insertions(+), 75 deletions(-) diff --git a/test/frontend/test_conference_creation.py b/test/frontend/test_conference_creation.py index 954b133d..660fd713 100644 --- a/test/frontend/test_conference_creation.py +++ b/test/frontend/test_conference_creation.py @@ -13,9 +13,6 @@ @pytest.mark.usefixtures("setup_conference_creation") class TestConferenceCreation: - def wait_until(self, delay, condition): - WebDriverWait(self.driver, delay).until(condition) - def test_name(self): driver = self.driver element_send_keys_by_id(driver, 'name', "Test Conference") @@ -33,17 +30,20 @@ def test_short(self): element_click_by_class_name(driver, 'btn-success') - xpath_alert = '//div[contains(@class,"alert-danger")]/strong' - self.wait_until(30, EC.presence_of_element_located((By.XPATH, xpath_alert))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.XPATH, '//div[contains(@class,"alert-danger")]/strong')) + ) assert "Conference short is already in use." in \ - driver.find_element_by_xpath(xpath_alert).text + driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text element_send_keys_by_id(driver, 'short', tc_num) element_click_by_class_name(driver, 'btn-success') - self.wait_until(30, EC.invisibility_of_element_located((By.XPATH, xpath_alert))) - assert len(driver.find_elements_by_xpath(xpath_alert)) == 0 + WebDriverWait(driver, 30).until( + EC.invisibility_of_element_located((By.XPATH, '//div[contains(@class,"alert-danger")]/strong')) + ) + assert len(driver.find_elements_by_xpath('//div[contains(@class,"alert-danger")]/strong')) == 0 #move to front page and check, whether conference is shown and marked as "Unpublished" driver.get("http://" + Cookies.get_host_ip() + ":9000/") @@ -55,13 +55,14 @@ def test_short(self): assert 'unpublished' in conf_div.find_element_by_xpath('..').get_attribute('class') assert len(conf_div.find_elements_by_xpath('./h4[contains(text(),"Test Conference")]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() - + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_published(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'published'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'published')) + ) element_click_by_id(driver, 'published') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -76,13 +77,15 @@ def test_published(self): assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Manage")]')) == 1 assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Conference Settings")]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) # thumbnail only shown if conference not active def test_thumbnail_url(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'thumbnail'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'thumbnail')) + ) element_send_keys_by_id(driver, 'thumbnail', 'https://portal.g-node.org/abstracts/bc14/BC14_icon.png') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -95,11 +98,14 @@ def test_thumbnail_url(self): assert len(conf_div.find_elements_by_xpath('..//div[contains(@class,"media-left")]//a/img[@src=' '"https://portal.g-node.org/abstracts/bc14/BC14_icon.png"]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_active(self): driver = self.driver - self.wait_until(30, EC.presence_of_element_located((By.ID, 'active'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'active')) + ) element_click_by_id(driver, 'active') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -115,12 +121,15 @@ def test_active(self): assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Manage")]')) == 1 assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Conference Settings")]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_submission(self): driver = self.driver - self.wait_until(30, EC.presence_of_element_located((By.ID, 'short'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'short')) + ) tc_num = element_get_attribute_by_id(driver, 'short', 'value') driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) @@ -130,7 +139,9 @@ def test_submission(self): element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') - self.wait_until(30, EC.presence_of_element_located((By.ID, 'submission'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'submission')) + ) element_click_by_id(driver, 'submission') element_click_by_class_name(driver, 'btn-success') @@ -141,12 +152,14 @@ def test_submission(self): '//li/a[contains(text(),"Submission")]')) == 1 assert len(driver.find_elements_by_xpath('//div[@class="jumbotron"]//a[contains(text(),"Submit")]')) == 1 - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_group(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'group'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'group')) + ) element_send_keys_by_id(driver, 'group', 'Test Group 1') def test_cite(self): @@ -157,8 +170,9 @@ def test_cite(self): def test_start_date(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'start'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'start')) + ) element_click_by_id(driver, 'start') move_to_element_by_id(driver, 'ui-datepicker-div') @@ -169,7 +183,9 @@ def test_start_date(self): element_click_by_class_name(driver, 'btn-success') # other elements might not be reachable immediately after click of "Save" button - self.wait_until(30, EC.presence_of_element_located((By.ID, 'start'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'start')) + ) assert "14" in element_get_attribute_by_xpath(driver, '//*[@id="start"]', 'value') old_date = element_get_attribute_by_id(driver, 'start', 'value') @@ -192,12 +208,14 @@ def test_start_date(self): conf_div = driver.find_element_by_xpath('//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') assert len(conf_div.find_elements_by_xpath('./p[contains(text(),"14")]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_end_date(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'end'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'end')) + ) element_click_by_id(driver, 'end') move_to_element_by_id(driver, 'ui-datepicker-div') @@ -208,7 +226,9 @@ def test_end_date(self): element_click_by_class_name(driver, 'btn-success') # other elements might not be reachable immediately after click of "Save" button - self.wait_until(30, EC.presence_of_element_located((By.ID, 'end'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'end')) + ) assert "16" in element_get_attribute_by_xpath(driver, '//*[@id="end"]', 'value') old_date = element_get_attribute_by_id(driver, 'end', 'value') @@ -231,12 +251,14 @@ def test_end_date(self): conf_div = driver.find_element_by_xpath('//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') assert len(conf_div.find_elements_by_xpath('./p[contains(text(),"16")]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_deadline(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'deadline'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'deadline')) + ) element_click_by_id(driver, 'deadline') driver.find_element_by_id('deadline').click() @@ -247,7 +269,9 @@ def test_deadline(self): element_click_by_class_name(driver, 'btn-success') - self.wait_until(30, EC.presence_of_element_located((By.ID, 'deadline'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'deadline')) + ) assert "10" in element_get_attribute_by_xpath(driver, '//*[@id="deadline"]', 'value') old_date = element_get_attribute_by_id(driver, 'deadline', 'value') @@ -262,8 +286,9 @@ def test_deadline(self): def test_logo_url(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'logo'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'logo')) + ) element_send_keys_by_id(driver, 'logo', 'https://portal.g-node.org/abstracts/bc18/BC18_header.jpg') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -277,12 +302,14 @@ def test_logo_url(self): assert len(conf_div.find_elements_by_xpath('.//p[contains(@data-bind,"logo")]//img[@src=' '"https://portal.g-node.org/abstracts/bc18/BC18_header.jpg"]')) == 1 - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_iosapp(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'iosapp'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'iosapp')) + ) element_send_keys_by_id(driver, 'iosapp', '999999999') def test_link(self): @@ -298,12 +325,14 @@ def test_link(self): '//div[@class="jumbotron"]/div[contains(@data-bind,"logo")]' '/a[contains(@href,"http://www.nncn.de/en/bernstein-conference/2014")]')) == 1 - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_description(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'desc'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'desc')) + ) element_send_keys_by_id(driver, 'desc', 'Important conference.') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -316,12 +345,14 @@ def test_description(self): assert "Important conference." in driver.find_element_by_xpath( '//div[@class="jumbotron"]/div[@class="jumbo-small"]/p[@class="paragraph-small"]').text - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_notice(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'notice'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'notice')) + ) element_send_keys_by_id(driver, 'notice', 'Check abstracts before submission!') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -331,12 +362,14 @@ def test_notice(self): assert len(driver.find_elements_by_xpath('//div[@class="jumbotron"]' '//p[contains(text(),"Check abstracts before submission!")]')) == 1 - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_presentation_preferences(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'presentation'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'presentation')) + ) element_click_by_id(driver, 'presentation') tc_num = element_get_attribute_by_id(driver, 'short', 'value') @@ -347,12 +380,15 @@ def test_presentation_preferences(self): assert len(driver.find_elements_by_class_name('poster-or-talk')) == 1 driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_add_topic(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'addTopic'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'addTopic')) + ) element_send_keys_by_id(driver, 'addTopic', 'Topic 1') driver.find_element_by_id('btn-add-topic').click() @@ -370,11 +406,14 @@ def test_add_topic(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") move_to_element_by_class_name(driver, 'topic') - - self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-topic'))) + WebDriverWait(driver, 10).until( + EC.visibility_of_element_located((By.ID, 'button-edit-topic')) + ) driver.find_element_by_id('button-edit-topic').click() - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]'))) + WebDriverWait(driver, 10).until( + EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) + ) assert len(driver.find_elements_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")]//input')) == 2 @@ -382,12 +421,15 @@ def test_add_topic(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_remove_topic(self): driver = self.driver + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'addTopic')) + ) - self.wait_until(30, EC.presence_of_element_located((By.ID, 'addTopic'))) move_to_element_by_xpath(driver, '//ul/li/span[contains(text(),"Topic 1")]/../a') driver.find_element_by_xpath('//ul/li/span[contains(text(),"Topic 1")]/../a').click() @@ -400,10 +442,14 @@ def test_remove_topic(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") move_to_element_by_class_name(driver, 'topic') - self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-topic'))) + WebDriverWait(driver, 10).until( + EC.visibility_of_element_located((By.ID, 'button-edit-topic')) + ) driver.find_element_by_id('button-edit-topic').click() - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]'))) + WebDriverWait(driver, 10).until( + EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) + ) assert len(driver.find_elements_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")]//input')) == 1 assert "Topic 2" in driver.find_element_by_xpath('//*[@id="topic-editor"]' @@ -412,12 +458,15 @@ def test_remove_topic(self): driver.find_element_by_xpath('//*[@id="topic-editor"]//button[@id="modal-button-ok"]').click() driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_maximum_abstract_length(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'mAbsLen'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'mAbsLen')) + ) # initial mAbsLen = 2000 element_send_keys_by_id(driver, 'mAbsLen', '300') @@ -427,7 +476,9 @@ def test_maximum_abstract_length(self): element_click_by_class_name(driver, 'btn-success') - self.wait_until(30, EC.presence_of_element_located((By.ID, 'mAbsLen'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'mAbsLen')) + ) move_to_element_by_id(driver, 'mAbsLen') assert "300" == driver.find_element_by_id('mAbsLen').get_attribute('value') @@ -436,29 +487,36 @@ def test_maximum_abstract_length(self): driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") move_to_element_by_class_name(driver, 'abstract-text') - - self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text'))) + WebDriverWait(driver, 10).until( + EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text')) + ) driver.find_element_by_id('button-edit-abstract-text').click() - self.wait_until(30, EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]'))) + WebDriverWait(driver, 30).until( + EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]')) + ) assert driver.find_element_by_xpath('//*[@id="abstract-text-editor"]' '//textarea[@id="text"]').get_attribute("maxlength") == '300' driver.find_element(By.XPATH, '//*[@id="abstract-text-editor"]//button[@id="modal-button-ok"]').click() driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_maximum_figures(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.ID, 'mFigs'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'mFigs')) + ) element_send_keys_by_id(driver, 'mFigs', '3') element_click_by_class_name(driver, 'btn-success') - self.wait_until(30, EC.presence_of_element_located((By.ID, 'mFigs'))) - + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.ID, 'mFigs')) + ) move_to_element_by_id(driver, 'mFigs') assert "3" == driver.find_element_by_id('mFigs').get_attribute('value') @@ -468,10 +526,14 @@ def test_maximum_figures(self): move_to_element_by_class_name(driver, 'figure') assert len(driver.find_elements_by_class_name('figure')) == 1 - self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-figure'))) + WebDriverWait(driver, 10).until( + EC.visibility_of_element_located((By.ID, 'button-edit-figure')) + ) driver.find_element_by_id('button-edit-figure').click() - self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]'))) + WebDriverWait(driver, 10).until( + EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]')) + ) assert len(driver.find_elements_by_xpath('//*[@id="figures-editor"]//div[@class="modal-body"]' '//div[contains(@data-bind, "figures().length>=3")]')) == 1 @@ -479,12 +541,15 @@ def test_maximum_figures(self): driver.find_element_by_xpath('//*[@id="figures-editor"]//button[@id="modal-button-ok"]').click() driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) def test_groups(self): driver = self.driver - - self.wait_until(30, EC.presence_of_element_located((By.XPATH, '//li/a[contains(@href,"groups")]'))) + WebDriverWait(driver, 30).until( + EC.presence_of_element_located((By.XPATH, '//li/a[contains(@href,"groups")]')) + ) move_to_element_by_xpath(driver, '//li/a[contains(@href,"groups")]') driver.find_element_by_xpath('//li/a[contains(@href,"groups")]').click() From 3f7641ba69bffaae3fad756db61a104328bfea97 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 28 Oct 2020 10:07:58 +0100 Subject: [PATCH 08/11] [test/frontend/conferences] Cleanup and desc The file was refactored for readability and detailled descriptions were added to clarify which actions are taking place since the xpath strings make it hard to identify the current action. --- test/frontend/test_conference_creation.py | 863 +++++++++++++--------- 1 file changed, 501 insertions(+), 362 deletions(-) diff --git a/test/frontend/test_conference_creation.py b/test/frontend/test_conference_creation.py index 660fd713..d9703d04 100644 --- a/test/frontend/test_conference_creation.py +++ b/test/frontend/test_conference_creation.py @@ -1,612 +1,751 @@ import pytest -import Cookies + from uuid import uuid1 + from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait -from conftest import element_send_keys_by_id, element_send_keys_by_class_name, element_send_keys_by_xpath, \ - element_click_by_id, element_click_by_class_name, element_click_by_xpath, \ - element_get_attribute_by_id, element_get_attribute_by_class_name, element_get_attribute_by_xpath, \ - move_to_element_by_id, move_to_element_by_class_name, move_to_element_by_xpath +import conftest +import Cookies @pytest.mark.usefixtures("setup_conference_creation") class TestConferenceCreation: + def wait_until(self, delay, condition): + WebDriverWait(self.driver, delay).until(condition) + def test_name(self): driver = self.driver - element_send_keys_by_id(driver, 'name', "Test Conference") - element_click_by_class_name(driver, 'btn-success') - #test automatic fill-in - assert "TC" in element_get_attribute_by_id(driver, 'short', 'value') - assert "500" == element_get_attribute_by_id(driver, 'mAbsLen', 'value') - assert "0" == element_get_attribute_by_id(driver, 'mFigs', 'value') + # Save a new conference with conference name only + conftest.element_send_keys_by_id(driver, 'name', "Test Conference") + conftest.element_click_by_class_name(driver, 'btn-success') + + # Test automatically filled in values + assert "TC" in conftest.element_get_attribute_by_id(driver, 'short', 'value') + assert "500" == conftest.element_get_attribute_by_id(driver, 'mAbsLen', 'value') + assert "0" == conftest.element_get_attribute_by_id(driver, 'mFigs', 'value') def test_short(self): driver = self.driver - tc_num = "TC" + str(uuid1())[0:8] - element_send_keys_by_id(driver, 'short', 'BC14') - - element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.XPATH, '//div[contains(@class,"alert-danger")]/strong')) - ) - assert "Conference short is already in use." in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + # Fill in existing conference short and save + conftest.element_send_keys_by_id(driver, 'short', 'BC14') + conftest.element_click_by_class_name(driver, 'btn-success') - element_send_keys_by_id(driver, 'short', tc_num) + xpath_alert = '//div[contains(@class,"alert-danger")]/strong' + # Wait for save alert to be displayed + self.wait_until(30, EC.presence_of_element_located((By.XPATH, xpath_alert))) + # Check save alert is displayed + test_msg = "Conference short is already in use." + assert test_msg in driver.find_element_by_xpath(xpath_alert).text - element_click_by_class_name(driver, 'btn-success') + # Fill in new conference short and save + conf_id = "TC%s" % str(uuid1())[0:10] + conftest.element_send_keys_by_id(driver, 'short', conf_id) + conftest.element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.invisibility_of_element_located((By.XPATH, '//div[contains(@class,"alert-danger")]/strong')) - ) - assert len(driver.find_elements_by_xpath('//div[contains(@class,"alert-danger")]/strong')) == 0 + # Check absence of save alert + self.wait_until(30, EC.invisibility_of_element_located((By.XPATH, xpath_alert))) + assert len(driver.find_elements_by_xpath(xpath_alert)) == 0 - #move to front page and check, whether conference is shown and marked as "Unpublished" + # Switch to start page driver.get("http://" + Cookies.get_host_ip() + ":9000/") - assert len(driver.find_elements_by_xpath('//div[@class="media-body"]/h4[@id="' + tc_num + '"]')) == 1 + # Check conference is present by short id and contains the conference name + xpath_div_conf = '//div[@class="media-body"]/h4[@id="%s" and contains(text(), "Test Conference")]' % conf_id + assert len(driver.find_elements_by_xpath(xpath_div_conf)) == 1 - move_to_element_by_xpath(driver, '//div[@class="media-body"]/h4[@id="' + tc_num + '"]') - conf_div = driver.find_element_by_xpath('//div[@class="media-body"]/h4[@id="' + tc_num + '"]/..') - assert 'unpublished' in conf_div.find_element_by_xpath('..').get_attribute('class') - assert len(conf_div.find_elements_by_xpath('./h4[contains(text(),"Test Conference")]')) == 1 + # Check new conference is present in the unpublished section + xpath_div = '//div[@class="media-body"]/h4[@id="%s"]/..' % conf_id + assert 'unpublished' in driver.find_element_by_xpath('%s/..' % xpath_div).get_attribute('class') + + # Move back to the conference settings page via link + driver.find_element_by_xpath('%s//a[contains(text(),"Conference Settings")]' % xpath_div).click() + # Switch to start page + driver.get("http://" + Cookies.get_host_ip() + ":9000/") # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_published(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'published')) - ) - element_click_by_id(driver, 'published') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Select published checkbox + self.wait_until(30, EC.presence_of_element_located((By.ID, 'published'))) + conftest.element_click_by_id(driver, 'published') + # Save conference + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') + + # Switch to start page driver.get("http://" + Cookies.get_host_ip() + ":9000/") - assert len(driver.find_elements_by_xpath('//div[@class="media-body"]/a[contains(@href,"' + tc_num + '")]')) == 1 + # Check that the conference is present by conference id + xpath_div_conf = '//div[@class="media-body"]/a[contains(@href,"%s")]' % conf_id + assert len(driver.find_elements_by_xpath(xpath_div_conf)) == 1 + + conf_div = driver.find_element_by_xpath(xpath_div_conf + '/..') - conf_div = driver.find_element_by_xpath('//div[@class="media-body"]/a[contains(@href,"' + tc_num + '")]/..') + # Check the conference is not in the unpublished section assert 'unpublished' not in conf_div.find_element_by_xpath('..').get_attribute('class') - assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Manage")]')) == 1 + # Check admin manage abstracts link is available + assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Manage abstracts")]')) == 1 + # Check admin conference settings link is available assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Conference Settings")]')) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) - # thumbnail only shown if conference not active def test_thumbnail_url(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'thumbnail')) - ) - element_send_keys_by_id(driver, 'thumbnail', 'https://portal.g-node.org/abstracts/bc14/BC14_icon.png') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # The thumbnail is only shown if a conference is not active + img_thumb = "https://portal.g-node.org/abstracts/bc14/BC14_icon.png" + + # Fill in thumbnail link + self.wait_until(30, EC.presence_of_element_located((By.ID, 'thumbnail'))) + conftest.element_send_keys_by_id(driver, 'thumbnail', img_thumb) + + # Save conference + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') + # Switch to start page driver.get("http://" + Cookies.get_host_ip() + ":9000/") - conf_div = driver.find_element_by_xpath('//div[@class="media-body"]/a[contains(@href,"' + tc_num + '")]/..') + # Select conference by conference id + xpath_div_conf = '//div[@class="media-body"]/a[contains(@href,"%s")]/..' % conf_id + conf_div = driver.find_element_by_xpath(xpath_div_conf) - assert len(conf_div.find_elements_by_xpath('..//div[contains(@class,"media-left")]//a/img[@src=' - '"https://portal.g-node.org/abstracts/bc14/BC14_icon.png"]')) == 1 + # Check conference thumbnail displayed + xpath_image = '..//div[contains(@class,"media-left")]//a/img[@src="%s"]' % img_thumb + assert len(conf_div.find_elements_by_xpath(xpath_image)) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_active(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'active')) - ) - element_click_by_id(driver, 'active') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Select 'active' checkbox + self.wait_until(30, EC.presence_of_element_located((By.ID, 'active'))) + conftest.element_click_by_id(driver, 'active') + # Save conference + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') + + # Switch to start page driver.get("http://" + Cookies.get_host_ip() + ":9000/") - assert len(driver.find_elements_by_xpath('//div[@class="jumbotron"]/h3' - '/a[contains(@href,"' + tc_num + '")]')) == 1 + # Find conference via conference id and check its in the jumbotron (active conference) section + xpath_div_conf = '//div[@class="jumbotron"]/h3/a[contains(@href,"%s")]' % conf_id + assert len(driver.find_elements_by_xpath(xpath_div_conf)) == 1 - move_to_element_by_xpath(driver, '//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]') - conf_div = driver.find_element_by_xpath('//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') + conf_div = driver.find_element_by_xpath('%s/../..' % xpath_div_conf) + # Check admin manage abstracts link is available assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Manage")]')) == 1 + # Check admin conference settings link is available assert len(conf_div.find_elements_by_xpath('.//a[contains(text(),"Conference Settings")]')) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_submission(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'short')) - ) - tc_num = element_get_attribute_by_id(driver, 'short', 'value') + # Fetch conference id from conference settings page + self.wait_until(30, EC.presence_of_element_located((By.ID, 'short'))) + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + + # Switch to conference start page + driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + conf_id) - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - assert len(driver.find_elements_by_xpath('//ul[contains(@class,"nav")]' - '//li/a[contains(text(),"Submission")]')) == 0 - assert len(driver.find_elements_by_xpath('//div[@class="jumbotron"]//a[contains(text(),"Submit")]')) == 0 + # Check that there is no submission text + xpath_submission = '//ul[contains(@class,"nav")]//li/a[contains(text(),"Submission")]' + assert len(driver.find_elements_by_xpath(xpath_submission)) == 0 + # Check that there is no submission submit abstract link + xpath_submit = '//div[@class="jumbotron"]//a[contains(text(),"Submit")]' + assert len(driver.find_elements_by_xpath(xpath_submit)) == 0 - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # Switch back to the conference settings page via the conference settings link + xpath_conf_setting = '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]' + conftest.element_click_by_xpath(driver, xpath_conf_setting) - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'submission')) - ) - element_click_by_id(driver, 'submission') + # Select 'submission' checkbox + self.wait_until(30, EC.presence_of_element_located((By.ID, 'submission'))) + conftest.element_click_by_id(driver, 'submission') - element_click_by_class_name(driver, 'btn-success') + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Switch to conference start page + driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + conf_id) - assert len(driver.find_elements_by_xpath('//ul[contains(@class,"nav")]' - '//li/a[contains(text(),"Submission")]')) == 1 - assert len(driver.find_elements_by_xpath('//div[@class="jumbotron"]//a[contains(text(),"Submit")]')) == 1 + # Check that there is a submission text + assert len(driver.find_elements_by_xpath(xpath_submission)) == 1 + # Check that there is a submission submit abstract link + assert len(driver.find_elements_by_xpath(xpath_submit)) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_group(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'group')) - ) - element_send_keys_by_id(driver, 'group', 'Test Group 1') + + # Fill in conference group + self.wait_until(30, EC.presence_of_element_located((By.ID, 'group'))) + test_val = "Test Group 1" + conftest.element_send_keys_by_id(driver, 'group', test_val) + + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') + + # Check value has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, 'group'))) + assert test_val in conftest.element_get_attribute_by_xpath(driver, '//*[@id="group"]', 'value') def test_cite(self): driver = self.driver - element_send_keys_by_id(driver, 'cite', 'The Test Conf, Somewhere, Sometime') - element_click_by_class_name(driver, 'btn-success') + # Fill in conference citation text + test_val = "The Test Conf, Somewhere, Sometime" + conftest.element_send_keys_by_id(driver, 'cite', test_val) + + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') + + # Check value has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, 'cite'))) + assert test_val in conftest.element_get_attribute_by_xpath(driver, '//*[@id="cite"]', 'value') def test_start_date(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'start')) - ) - element_click_by_id(driver, 'start') - move_to_element_by_id(driver, 'ui-datepicker-div') + # Select start date via date picker to the 14. of the next month + self.wait_until(30, EC.presence_of_element_located((By.ID, 'start'))) + test_val = "14" + conftest.element_click_by_id(driver, 'start') + driver.find_element_by_xpath('//a[contains(@class,"ui-datepicker-next")]').click() - driver.find_element_by_xpath('//div[@id="ui-datepicker-div"]//a[contains(text(), "14")]').click() + driver.find_element_by_xpath('//div[@id="ui-datepicker-div"]//a[contains(text(), "%s")]' % test_val).click() driver.find_element_by_xpath('//button[contains(@class, "datepicker-close")]').click() - element_click_by_class_name(driver, 'btn-success') - - # other elements might not be reachable immediately after click of "Save" button - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'start')) - ) - assert "14" in element_get_attribute_by_xpath(driver, '//*[@id="start"]', 'value') + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') - old_date = element_get_attribute_by_id(driver, 'start', 'value') - element_send_keys_by_id(driver, 'start', '99/99/9999') + # Check that the date has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, 'start'))) + assert test_val in conftest.element_get_attribute_by_xpath(driver, '//*[@id="start"]', 'value') - element_click_by_id(driver, 'mFigs') + # Check start date cannot be set to invalid values + old_date = conftest.element_get_attribute_by_id(driver, 'start', 'value') + # Check invalid date + conftest.element_send_keys_by_id(driver, 'start', '99/99/9999') + # Switch focus + conftest.element_click_by_id(driver, 'mFigs') - move_to_element_by_id(driver, 'start') - assert old_date in element_get_attribute_by_id(driver, 'start', 'value') + # Check date value has not been changed + assert old_date in conftest.element_get_attribute_by_id(driver, 'start', 'value') + # Check date cannot be set to invalid string driver.find_element_by_id('start').send_keys('hello') - assert old_date in element_get_attribute_by_id(driver, 'start', 'value') - - element_click_by_id(driver, 'mFigs') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') + assert old_date in conftest.element_get_attribute_by_id(driver, 'start', 'value') + # Switch to start page + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') driver.get("http://" + Cookies.get_host_ip() + ":9000/") - move_to_element_by_xpath(driver, '//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') - conf_div = driver.find_element_by_xpath('//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') - assert len(conf_div.find_elements_by_xpath('./p[contains(text(),"14")]')) == 1 + # Select conference by conference id + div_conf = '//div[@class="jumbotron"]/h3/a[contains(@href,"%s")]/../..' % conf_id + conf_div = driver.find_element_by_xpath(div_conf) + + # Check conference contains changed start date + assert len(conf_div.find_elements_by_xpath('./p[contains(text(),"%s")]' % test_val)) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_end_date(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'end')) - ) - element_click_by_id(driver, 'end') - move_to_element_by_id(driver, 'ui-datepicker-div') + # Select end date via date picker to the 16. of the next month + self.wait_until(30, EC.presence_of_element_located((By.ID, 'end'))) + test_val = "16" + conftest.element_click_by_id(driver, 'end') + driver.find_element_by_xpath('//a[contains(@class,"ui-datepicker-next")]').click() - driver.find_element_by_xpath('//div[@id="ui-datepicker-div"]//a[contains(text(), "16")]').click() + driver.find_element_by_xpath('//div[@id="ui-datepicker-div"]//a[contains(text(), "%s")]' % test_val).click() driver.find_element_by_xpath('//button[contains(@class, "datepicker-close")]').click() - element_click_by_class_name(driver, 'btn-success') - - # other elements might not be reachable immediately after click of "Save" button - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'end')) - ) - assert "16" in element_get_attribute_by_xpath(driver, '//*[@id="end"]', 'value') + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') - old_date = element_get_attribute_by_id(driver, 'end', 'value') - element_send_keys_by_id(driver, 'end', '99/99/9999') + # Check that date has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, 'end'))) + assert test_val in conftest.element_get_attribute_by_xpath(driver, '//*[@id="end"]', 'value') - element_click_by_id(driver, 'mFigs') + # Check date cannot be set to invalid values + old_date = conftest.element_get_attribute_by_id(driver, 'end', 'value') + # Check invalid date + conftest.element_send_keys_by_id(driver, 'end', '99/99/9999') + # Switch focus + conftest.element_click_by_id(driver, 'mFigs') - move_to_element_by_id(driver, 'end') - assert old_date in element_get_attribute_by_id(driver, 'end', 'value') + # Check date has not been changed + assert old_date in conftest.element_get_attribute_by_id(driver, 'end', 'value') + # Check date cannot be set to invalid string driver.find_element_by_id('end').send_keys('hello') - assert old_date in element_get_attribute_by_id(driver, 'end', 'value') - - element_click_by_id(driver, 'mFigs') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') + assert old_date in conftest.element_get_attribute_by_id(driver, 'end', 'value') + # Switch to start page + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') driver.get("http://" + Cookies.get_host_ip() + ":9000/") - move_to_element_by_xpath(driver, '//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') - conf_div = driver.find_element_by_xpath('//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') - assert len(conf_div.find_elements_by_xpath('./p[contains(text(),"16")]')) == 1 + # Select conference by conference id + xpath_div_conf = '//div[@class="jumbotron"]/h3/a[contains(@href,"' + conf_id + '")]/../..' + conf_div = driver.find_element_by_xpath(xpath_div_conf) + + # Check conference contains changed end date + assert len(conf_div.find_elements_by_xpath('./p[contains(text(),"%s")]' % test_val)) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_deadline(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'deadline')) - ) - element_click_by_id(driver, 'deadline') + + # Select deadline date via date picker to the 10. of the next month + self.wait_until(30, EC.presence_of_element_located((By.ID, 'deadline'))) + test_val = "10" + conftest.element_click_by_id(driver, 'deadline') driver.find_element_by_id('deadline').click() - move_to_element_by_id(driver, 'ui-datepicker-div') driver.find_element_by_xpath('//a[contains(@class,"ui-datepicker-next")]').click() - driver.find_element_by_xpath('//div[@id="ui-datepicker-div"]//a[contains(text(), "10")]').click() + driver.find_element_by_xpath('//div[@id="ui-datepicker-div"]//a[contains(text(), "%s")]' % test_val).click() driver.find_element_by_xpath('//button[contains(@class, "datepicker-close")]').click() - element_click_by_class_name(driver, 'btn-success') + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'deadline')) - ) - assert "10" in element_get_attribute_by_xpath(driver, '//*[@id="deadline"]', 'value') + self.wait_until(30, EC.presence_of_element_located((By.ID, 'deadline'))) + assert test_val in conftest.element_get_attribute_by_xpath(driver, '//*[@id="deadline"]', 'value') - old_date = element_get_attribute_by_id(driver, 'deadline', 'value') - element_send_keys_by_id(driver, 'deadline', '99/99/9999') - element_click_by_id(driver, "mFigs") + old_date = conftest.element_get_attribute_by_id(driver, 'deadline', 'value') + conftest.element_send_keys_by_id(driver, 'deadline', '99/99/9999') + conftest.element_click_by_id(driver, "mFigs") - assert old_date in element_get_attribute_by_id(driver, 'deadline', 'value') + assert old_date in conftest.element_get_attribute_by_id(driver, 'deadline', 'value') driver.find_element_by_id('deadline').send_keys('hello') - element_click_by_id(driver, "mFigs") - assert old_date in element_get_attribute_by_id(driver, 'deadline', 'value') - element_click_by_id(driver, "mFigs") + conftest.element_click_by_id(driver, "mFigs") + assert old_date in conftest.element_get_attribute_by_id(driver, 'deadline', 'value') + conftest.element_click_by_id(driver, "mFigs") def test_logo_url(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'logo')) - ) - element_send_keys_by_id(driver, 'logo', 'https://portal.g-node.org/abstracts/bc18/BC18_header.jpg') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Conference banner url + img_header = 'https://portal.g-node.org/abstracts/bc18/BC18_header.jpg' + + # Set conference banner url + self.wait_until(30, EC.presence_of_element_located((By.ID, 'logo'))) + conftest.element_send_keys_by_id(driver, 'logo', img_header) + # Save conference + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') + + # Switch to start page driver.get("http://" + Cookies.get_host_ip() + ":9000/") - move_to_element_by_xpath(driver, '//div[@class="jumbotron"]/h3/a[contains(@href,"' + tc_num + '")]/../..') - conf_div = driver.find_element_by_xpath('//div[@class="jumbotron"]/h3' - '/a[contains(@href,"' + tc_num + '")]/../..') - assert len(conf_div.find_elements_by_xpath('.//p[contains(@data-bind,"logo")]//img[@src=' - '"https://portal.g-node.org/abstracts/bc18/BC18_header.jpg"]')) == 1 + # Select conference div by conference id + xpath_tcnum = '//div[@class="jumbotron"]/h3/a[contains(@href,"%s")]/../..' % conf_id + conf_div = driver.find_element_by_xpath(xpath_tcnum) + + # Check the banner is displayed + xpath_img_header = './/p[contains(@data-bind,"logo")]//img[@src="%s"]' % img_header + assert len(conf_div.find_elements_by_xpath(xpath_img_header)) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_iosapp(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'iosapp')) - ) - element_send_keys_by_id(driver, 'iosapp', '999999999') + + # Fill in iosapp entry + self.wait_until(30, EC.presence_of_element_located((By.ID, 'iosapp'))) + test_val = "999999999" + conftest.element_send_keys_by_id(driver, 'iosapp', test_val) + + # Save conference + conftest.element_click_by_class_name(driver, 'btn-success') + + # Check value has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, 'iosapp'))) + assert test_val in conftest.element_get_attribute_by_xpath(driver, '//*[@id="iosapp"]', 'value') def test_link(self): driver = self.driver - element_send_keys_by_id(driver, 'link', 'http://www.nncn.de/en/bernstein-conference/2014') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Fill in conference link + conf_link = 'http://www.nncn.de/en/bernstein-conference/2014' + conftest.element_send_keys_by_id(driver, 'link', conf_link) + + # Save conference + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Switch to conference main page + driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + conf_id) - assert len(driver.find_elements_by_xpath( - '//div[@class="jumbotron"]/div[contains(@data-bind,"logo")]' - '/a[contains(@href,"http://www.nncn.de/en/bernstein-conference/2014")]')) == 1 + # Check the conference banner contains the set conference link + xpath_link = '//div[@class="jumbotron"]/div[contains(@data-bind,"logo")]/a[contains(@href,"%s")]' % conf_link + assert len(driver.find_elements_by_xpath(xpath_link)) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_description(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'desc')) - ) - element_send_keys_by_id(driver, 'desc', 'Important conference.') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Fill in conference description + self.wait_until(30, EC.presence_of_element_located((By.ID, 'desc'))) + test_val = "Important conference." + conftest.element_send_keys_by_id(driver, 'desc', test_val) + + # Save conference settings + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') + + # Switch to start page + driver.get("http://" + Cookies.get_host_ip() + ":9000") + + # Select conference by conference id + xpath_conf_div = '//div[@class="jumbotron"]/h3/a[contains(@href,"%s")]/../..' % conf_id + conf_div = driver.find_element_by_xpath(xpath_conf_div) - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Check conference jumbotron contains the description + xpath_para = './div[@class="jumbo-small"]/p[contains(text(),"%s")]' % test_val + assert len(conf_div.find_elements_by_xpath(xpath_para)) == 1 - move_to_element_by_xpath(driver, '//div[@class="jumbotron"]' - '/div[@class="jumbo-small"]/p[@class="paragraph-small"]') - assert "Important conference." in driver.find_element_by_xpath( - '//div[@class="jumbotron"]/div[@class="jumbo-small"]/p[@class="paragraph-small"]').text + # Switch to conference main page + driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + conf_id) + + # Check the conference description is displayed + xpath_para = '//div[@class="jumbotron"]/div[@class="jumbo-small"]/p[@class="paragraph-small"]' + assert test_val in driver.find_element_by_xpath(xpath_para).text # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_notice(self): + # Test conference wide note driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'notice')) - ) - element_send_keys_by_id(driver, 'notice', 'Check abstracts before submission!') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Fill in conference note + self.wait_until(30, EC.presence_of_element_located((By.ID, 'notice'))) + test_val = 'Check abstracts before submission!' + conftest.element_send_keys_by_id(driver, 'notice', test_val) + + # Save conference settings + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') + + # Switch to conference main page + driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + conf_id) + + # Check notice is displayed as first jumbotron + xpath_check = '//div[@class="jumbotron"]//p[contains(text(),"%s")]' % test_val + assert len(driver.find_elements_by_xpath(xpath_check)) == 1 - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - assert len(driver.find_elements_by_xpath('//div[@class="jumbotron"]' - '//p[contains(text(),"Check abstracts before submission!")]')) == 1 + # Switch to conference abstracts page + driver.get("http://%s:9000/conference/%s/abstracts" % (Cookies.get_host_ip(), conf_id)) + + # Check notice is displayed as first jumbotron + xpath_check = '//div[@class="jumbotron"]//p[contains(text(),"%s")]' % test_val + assert len(driver.find_elements_by_xpath(xpath_check)) == 1 + + # Switch to start page + driver.get("http://" + Cookies.get_host_ip() + ":9000") + + # Check notice is not displayed + xpath_check = '//div[@class="jumbotron"]//p[contains(text(),"%s")]' % test_val + assert len(driver.find_elements_by_xpath(xpath_check)) == 0 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_presentation_preferences(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'presentation')) - ) - element_click_by_id(driver, 'presentation') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Select presentation check box + self.wait_until(30, EC.presence_of_element_located((By.ID, 'presentation'))) + conftest.element_click_by_id(driver, 'presentation') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # Save conference settings + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') - assert len(driver.find_elements_by_class_name('poster-or-talk')) == 1 + url_submission = "http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id) + url_conf_settings = "http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id) - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Switch to the conference abstract submission page + driver.get(url_submission) + + # Check that the presentation type option is available + assert len(driver.find_elements_by_class_name('poster-or-talk')) == 1 # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_add_topic(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'addTopic')) - ) - element_send_keys_by_id(driver, 'addTopic', 'Topic 1') - driver.find_element_by_id('btn-add-topic').click() - assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"Topic 1")]')) == 1 - - element_send_keys_by_id(driver, 'addTopic', 'Topic 2') + # Add an abstract topic + self.wait_until(30, EC.presence_of_element_located((By.ID, 'addTopic'))) + conftest.element_send_keys_by_id(driver, 'addTopic', 'Topic A') driver.find_element_by_id('btn-add-topic').click() - assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"Topic 2")]')) == 1 + # Check topic has been added + assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"Topic A")]')) == 1 - tc_num = element_get_attribute_by_id(driver, 'short', 'value') + # Add second topic + conftest.element_send_keys_by_id(driver, 'addTopic', 'Topic B') + driver.find_element_by_id('btn-add-topic').click() + assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"Topic B")]')) == 1 - element_click_by_class_name(driver, 'btn-success') + # Save conference settings + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # Switch to the conference abstract submission page + driver.get("http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id)) - move_to_element_by_class_name(driver, 'topic') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-topic')) - ) + # Open abstract topic modal + conftest.move_to_element_by_class_name(driver, 'topic') + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-topic'))) driver.find_element_by_id('button-edit-topic').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) - ) + # Check there are two options available + xpath_radio = '//*[@id="topic-editor"]//div[contains(@class, "radio")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_radio))) - assert len(driver.find_elements_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")]//input')) == 2 + xpath_radio_input = '//*[@id="topic-editor"]//div[contains(@class, "radio")]//input' + assert len(driver.find_elements_by_xpath(xpath_radio_input)) == 2 + # Close topic modal driver.find_element_by_xpath('//*[@id="topic-editor"]//button[@id="modal-button-ok"]').click() - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) - # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_remove_topic(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'addTopic')) - ) - move_to_element_by_xpath(driver, '//ul/li/span[contains(text(),"Topic 1")]/../a') - driver.find_element_by_xpath('//ul/li/span[contains(text(),"Topic 1")]/../a').click() + self.wait_until(30, EC.presence_of_element_located((By.ID, 'addTopic'))) + val_remove = "Topic A" + val_remain = "Topic B" + + # Remove first topic + xpath_topic_link = '//ul/li/span[contains(text(),"%s")]/../a' % val_remove + driver.find_element_by_xpath(xpath_topic_link).click() - assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"Topic 1")]')) == 0 - assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"Topic 2")]')) == 1 + # Check topic has been removed + assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"%s")]' % val_remove)) == 0 + assert len(driver.find_elements_by_xpath('//ul/li/span[contains(text(),"%s")]' % val_remain)) == 1 - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # Save conference settings + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + conftest.element_click_by_class_name(driver, 'btn-success') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # Switch to the conference abstract submission page + driver.get("http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id)) - move_to_element_by_class_name(driver, 'topic') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-topic')) - ) + # Open abstract topic modal + conftest.move_to_element_by_class_name(driver, 'topic') + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-topic'))) driver.find_element_by_id('button-edit-topic').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="topic-editor"]//div[contains(@class, "radio")]')) - ) + xpath_radio = '//*[@id="topic-editor"]//div[contains(@class, "radio")]' + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, xpath_radio))) - assert len(driver.find_elements_by_xpath('//*[@id="topic-editor"]//div[contains(@class, "radio")]//input')) == 1 - assert "Topic 2" in driver.find_element_by_xpath('//*[@id="topic-editor"]' - '//div[contains(@class, "radio")]//span').text + # Check that there is one option available + xpath_radio_input = '//*[@id="topic-editor"]//div[contains(@class, "radio")]//input' + assert len(driver.find_elements_by_xpath(xpath_radio_input)) == 1 - driver.find_element_by_xpath('//*[@id="topic-editor"]//button[@id="modal-button-ok"]').click() + xpath_radio_span = '//*[@id="topic-editor"]//div[contains(@class, "radio")]//span' + assert val_remain in driver.find_element_by_xpath(xpath_radio_span).text + assert val_remove not in driver.find_element_by_xpath(xpath_radio_span).text - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Close topic modal + driver.find_element_by_xpath('//*[@id="topic-editor"]//button[@id="modal-button-ok"]').click() # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_maximum_abstract_length(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mAbsLen')) - ) - # initial mAbsLen = 2000 - element_send_keys_by_id(driver, 'mAbsLen', '300') - assert "Changing to shorter abstract length causes cut-offs" in \ - driver.find_element_by_xpath('//div[contains(@class,"form-group")]' - '/div[contains(@class,"alert-danger")]').text + abstract_id = 'mAbsLen' + self.wait_until(30, EC.presence_of_element_located((By.ID, abstract_id))) + + # Set maximum abstract length + test_abstract_len = "300" + conftest.element_send_keys_by_id(driver, abstract_id, test_abstract_len) - element_click_by_class_name(driver, 'btn-success') + # Check warning message when a set abstract length is shortened + test_msg = "Changing to shorter abstract length causes cut-offs" + xpath_alert = '//div[contains(@class,"form-group")]/div[contains(@class,"alert-danger")]' + assert test_msg in driver.find_element_by_xpath(xpath_alert).text - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mAbsLen')) - ) - move_to_element_by_id(driver, 'mAbsLen') - assert "300" == driver.find_element_by_id('mAbsLen').get_attribute('value') + # Save conference settings + conftest.element_click_by_class_name(driver, 'btn-success') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') + # Check abstract length has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, abstract_id))) + assert test_abstract_len == driver.find_element_by_id(abstract_id).get_attribute('value') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # Switch to the conference abstract submission page + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + driver.get("http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id)) - move_to_element_by_class_name(driver, 'abstract-text') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text')) - ) + # Open abstract text modal + conftest.move_to_element_by_class_name(driver, 'abstract-text') + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text'))) driver.find_element_by_id('button-edit-abstract-text').click() - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]')) - ) + self.wait_until(30, EC.visibility_of_element_located((By.XPATH, '//*[@id="abstract-text-editor"]'))) - assert driver.find_element_by_xpath('//*[@id="abstract-text-editor"]' - '//textarea[@id="text"]').get_attribute("maxlength") == '300' - driver.find_element(By.XPATH, '//*[@id="abstract-text-editor"]//button[@id="modal-button-ok"]').click() + # Check maximum length message + xpath_text = '//*[@id="abstract-text-editor"]//textarea[@id="text"]' + assert driver.find_element_by_xpath(xpath_text).get_attribute("maxlength") == test_abstract_len - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Close abstract text modal + xpath_modal = '//*[@id="abstract-text-editor"]//button[@id="modal-button-ok"]' + driver.find_element(By.XPATH, xpath_modal).click() # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_maximum_figures(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mFigs')) - ) - element_send_keys_by_id(driver, 'mFigs', '3') - element_click_by_class_name(driver, 'btn-success') + # Switch to the conference abstract submission page + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'short'))) + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + driver.get("http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id)) + + # Check figure modal is not available + assert len(driver.find_elements_by_class_name('figure')) == 0 + + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) + + # Set abstract figure number + fig_id = "mFigs" + test_fig_num = "3" + self.wait_until(30, EC.presence_of_element_located((By.ID, fig_id))) + conftest.element_send_keys_by_id(driver, fig_id, test_fig_num) - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.ID, 'mFigs')) - ) - move_to_element_by_id(driver, 'mFigs') - assert "3" == driver.find_element_by_id('mFigs').get_attribute('value') + # Save conference settings + conftest.element_click_by_class_name(driver, 'btn-success') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # Check figure number has been set + self.wait_until(30, EC.presence_of_element_located((By.ID, fig_id))) + assert test_fig_num == driver.find_element_by_id(fig_id).get_attribute('value') - move_to_element_by_class_name(driver, 'figure') + # Switch to the conference abstract submission page + conf_id = conftest.element_get_attribute_by_id(driver, 'short', 'value') + driver.get("http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id)) + + # Check figure section is available assert len(driver.find_elements_by_class_name('figure')) == 1 - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-figure')) - ) + # Open figure modal + conftest.move_to_element_by_class_name(driver, 'figure') + self.wait_until(10, EC.visibility_of_element_located((By.ID, 'button-edit-figure'))) driver.find_element_by_id('button-edit-figure').click() - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]')) - ) - - assert len(driver.find_elements_by_xpath('//*[@id="figures-editor"]//div[@class="modal-body"]' - '//div[contains(@data-bind, "figures().length>=3")]')) == 1 + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]'))) - driver.find_element_by_xpath('//*[@id="figures-editor"]//button[@id="modal-button-ok"]').click() + # Check figure number + xpath_fig_len = '//*[@id="figures-editor"]//div[@class="modal-body"]' \ + '//div[contains(@data-bind, "figures().length>=%s")]' % test_fig_num + assert len(driver.find_elements_by_xpath(xpath_fig_len)) == 1 - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # Close figure modal + xpath_modal = '//*[@id="figures-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_modal).click() # Switch back to the conference settings page - driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), tc_num)) + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) def test_groups(self): driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.XPATH, '//li/a[contains(@href,"groups")]')) - ) - - move_to_element_by_xpath(driver, '//li/a[contains(@href,"groups")]') - driver.find_element_by_xpath('//li/a[contains(@href,"groups")]').click() - - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() - - assert "Prefix, short and long entries have to be provided!" in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text - - move_to_element_by_id(driver, 'ngPrefix') - driver.find_element_by_id('ngPrefix').send_keys("u") - - move_to_element_by_id(driver, 'ngShort') - driver.find_element_by_id('ngShort').send_keys("3") - - move_to_element_by_id(driver, 'ngName') - driver.find_element_by_id('ngName').send_keys("3") - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() + # Set conference abstract groups + xpath_groups = '//li/a[contains(@href,"groups")]' + self.wait_until(30, EC.presence_of_element_located((By.XPATH, xpath_groups))) - assert "Prefix can only contain numbers!" in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + # Switch to conference groups tab + driver.find_element_by_xpath(xpath_groups).click() - element_send_keys_by_id(driver, 'ngPrefix', '1.2') + # Add empty group + xpath_btn_new_group = '//tr[@id="newGroup"]//td/button' + driver.find_element_by_xpath(xpath_btn_new_group).click() - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() + # Check that empty group cannot be saved + xpath_alert = '//div[contains(@class,"alert-danger")]/strong' + test_msg_full_entry = "Prefix, short and long entries have to be provided!" + assert test_msg_full_entry in driver.find_element_by_xpath(xpath_alert).text - assert "Prefix can only contain numbers!" in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + # Set all fields of the added group entry to invalid values + id_prefix = "ngPrefix" + id_short = "ngShort" + id_name = "ngName" + driver.find_element_by_id(id_prefix).send_keys("u") + driver.find_element_by_id(id_short).send_keys("3") + driver.find_element_by_id(id_name).send_keys("3") - element_send_keys_by_id(driver, 'ngPrefix', '1') + # Check invalid values cannot be saved + driver.find_element_by_xpath(xpath_btn_new_group).click() - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() + # Check invalid prefix message + test_msg_num_only = "Prefix can only contain numbers!" + assert test_msg_num_only in driver.find_element_by_xpath(xpath_alert).text - assert "Name cannot contain only numbers!" in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + # Change prefix to invalid content + conftest.element_send_keys_by_id(driver, id_prefix, '1.2') + driver.find_element_by_xpath(xpath_btn_new_group).click() + assert test_msg_num_only in driver.find_element_by_xpath(xpath_alert).text - element_send_keys_by_id(driver, 'ngName', 'Group 1') + # Change prefix to valid content + conftest.element_send_keys_by_id(driver, id_prefix, '1') + driver.find_element_by_xpath(xpath_btn_new_group).click() - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() + # Check long name invalid content + test_msg_name_char = "Name cannot contain only numbers!" + assert test_msg_name_char in driver.find_element_by_xpath(xpath_alert).text - assert "Short cannot contain only numbers!" in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + # Change long name to valid content + conftest.element_send_keys_by_id(driver, id_name, 'Group 1') + driver.find_element_by_xpath(xpath_btn_new_group).click() - element_send_keys_by_id(driver, 'ngShort', 'G1') + # Check short name invalid content + test_msg_short_char = "Short cannot contain only numbers!" + assert test_msg_short_char in driver.find_element_by_xpath(xpath_alert).text - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() + # Change short name to valid content + conftest.element_send_keys_by_id(driver, id_short, 'G1') + driver.find_element_by_xpath(xpath_btn_new_group).click() - assert len(driver.find_elements_by_xpath('//div[contains(@class,"alert-danger")]/strong')) == 0 + assert len(driver.find_elements_by_xpath(xpath_alert)) == 0 - move_to_element_by_xpath(driver, '//*[@id="groups"]/div/button[contains(@class,"btn-success")]') - driver.find_element_by_xpath('//*[@id="groups"]/div/button[contains(@class,"btn-success")]').click() + xpath_btn_success = '//*[@id="groups"]/div/button[contains(@class,"btn-success")]' + driver.find_element_by_xpath(xpath_btn_success).click() - assert len(driver.find_elements_by_xpath('//div[contains(@class,"alert-danger")]/strong')) == 0 + assert len(driver.find_elements_by_xpath(xpath_alert)) == 0 From abe2c78156c8fba808ff952bc683198c73ea09ce Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 28 Oct 2020 14:19:31 +0100 Subject: [PATCH 09/11] [readme] Add link to frontend test documentation --- Readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Readme.md b/Readme.md index 87d4c5bc..08a0974d 100644 --- a/Readme.md +++ b/Readme.md @@ -24,3 +24,9 @@ The current version is stable. A previous version of the application can be found in the "oldstable" branch. Please find the latest release notes in the [release section](https://github.com/G-Node/GCA-Web/releases). + + +## Frontend tests using Selenium + +The application suite provides frontend test using Selenium. A full setup and usage description can be found in the +[frontend test readme](./test/frontend/Readme.md). From afb0be1113ffe761bf611b0e892e70bd926af18d Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 28 Oct 2020 14:29:53 +0100 Subject: [PATCH 10/11] [views] Add dynamic (c) year --- app/views/mob_template.scala.html | 8 ++++++-- app/views/template.scala.html | 7 ++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/views/mob_template.scala.html b/app/views/mob_template.scala.html index 08c60958..22959a12 100644 --- a/app/views/mob_template.scala.html +++ b/app/views/mob_template.scala.html @@ -197,11 +197,15 @@
  • Datenschutz
  • -

    The G-Node Conference Site — © G-Node 2019

    +
    +

    The G-Node Conference Site — © + G-Node 2013- + +

    +
    - diff --git a/app/views/template.scala.html b/app/views/template.scala.html index 73f8eefb..0b4ceb2c 100644 --- a/app/views/template.scala.html +++ b/app/views/template.scala.html @@ -266,7 +266,12 @@
  • Datenschutz
  • -

    The G-Node Conference Site — © G-Node 2019

    +
    +

    The G-Node Conference Site — © + G-Node 2013- + +

    +
    From 9347c10ae641ca65d26c66e80f2ab05c42c01885 Mon Sep 17 00:00:00 2001 From: "M. Sonntag" Date: Wed, 28 Oct 2020 15:09:28 +0100 Subject: [PATCH 11/11] Update mathjax version to 2.7.7 Closes #506 --- CHANGELOG.md | 1 + app/controllers/Application.scala | 4 ++-- app/views/components/mathjax.scala.html | 2 +- public/service-worker.js | 14 +++++++------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aa2048c..e374ec25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The current project setup is still using an outdated build tool (`activator`) an - Added error messages on abstract reference validation, if the input is numeric. For details see issue #499. - The outdated mapbox.js plugin was updated to the latest version. See issue #510 for details. - An issue was resolved where the sortid of an abstract was removed when an abstract was re-submitted. See issue #507 for details. +- The outdated mathjax.js plugin was updated to version 2.7.7. See issue #506 for details. # Release v1.2 diff --git a/app/controllers/Application.scala b/app/controllers/Application.scala index a5eb3926..ba03ef36 100644 --- a/app/controllers/Application.scala +++ b/app/controllers/Application.scala @@ -268,8 +268,8 @@ class Application(implicit val env: Environment[Login, CachedCookieAuthenticator |https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-debug.js |https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.1/jquery-ui-timepicker-addon.min.css |https://fonts.googleapis.com/css?family=EB+Garamond|Open+Sans - |https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/MathJax.js?delayStartupUntil=configured - |https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/extensions/MathMenu.js + |https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?delayStartupUntil=configured + |https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/extensions/MathMenu.js | |# Styles |/assets/stylesheets/_g-node-bootstrap.less diff --git a/app/views/components/mathjax.scala.html b/app/views/components/mathjax.scala.html index e87259f7..fa756551 100644 --- a/app/views/components/mathjax.scala.html +++ b/app/views/components/mathjax.scala.html @@ -1,7 +1,7 @@ @() - +