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/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). 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 @@ @() - + +

+ - 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- + +

    +
    diff --git a/public/service-worker.js b/public/service-worker.js index db893ef3..b4a03f19 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,4 +1,4 @@ -self._cacheVersion = "v20"; +self._cacheVersion = "v21"; self.resourcesToCache = [ // Views @@ -69,12 +69,12 @@ self.resourcesToCache = [ "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.3/extensions/tex2jax.js", - "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/jax/output/HTML-CSS/config.js", - "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/jax/input/TeX/config.js", - "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/extensions/MathZoom.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", + "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/extensions/tex2jax.js", + "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/jax/output/HTML-CSS/config.js", + "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/jax/input/TeX/config.js", + "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/extensions/MathZoom.js", // Styles "/assets/stylesheets/_g-node-bootstrap.less", 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 + diff --git a/test/frontend/test_conference_creation.py b/test/frontend/test_conference_creation.py index ef310c73..d9703d04 100644 --- a/test/frontend/test_conference_creation.py +++ b/test/frontend/test_conference_creation.py @@ -1,593 +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') - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # 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(), 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('//div[@class="media-body"]/a[contains(@href,"' + tc_num + '")]/..') + conf_div = driver.find_element_by_xpath(xpath_div_conf + '/..') + + # 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 - 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(), 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 - 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(), 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 - 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(), 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 - 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(), 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') + # Save conference + conftest.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') + # 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') - old_date = element_get_attribute_by_id(driver, 'start', 'value') - element_send_keys_by_id(driver, 'start', '99/99/9999') + # 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') - 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) - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # 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(), 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') + # Save conference + conftest.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') + # 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') - old_date = element_get_attribute_by_id(driver, 'end', 'value') - element_send_keys_by_id(driver, 'end', '99/99/9999') + # 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') - 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) - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # 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(), 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) - conf_div.find_element_by_xpath('.//a[contains(text(),"Conference Settings")]').click() + # 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(), 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 - 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(), 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") - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num) + # 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) - 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 + # 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 - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # 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(), 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) - 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 + # 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 - element_click_by_xpath(driver, '//div[@class="jumbotron"]//a[contains(text(),"Conference Settings")]') + # 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(), 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') + 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) + + # 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 - 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(), 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) - - 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(), 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" - 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 + # Remove first topic + xpath_topic_link = '//ul/li/span[contains(text(),"%s")]/../a' % val_remove + driver.find_element_by_xpath(xpath_topic_link).click() - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - element_click_by_class_name(driver, 'btn-success') + # 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 - 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') - move_to_element_by_class_name(driver, 'topic') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-topic')) - ) + # Switch to the conference abstract submission page + driver.get("http://%s:9000/conference/%s/submission" % (Cookies.get_host_ip(), conf_id)) + + # 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))) + + # 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 - 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 + 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 + # 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) - 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(), 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))) - element_click_by_class_name(driver, 'btn-success') + # Set maximum abstract length + test_abstract_len = "300" + conftest.element_send_keys_by_id(driver, abstract_id, test_abstract_len) - 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') + # 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 - tc_num = element_get_attribute_by_id(driver, 'short', 'value') + # Save conference settings + conftest.element_click_by_class_name(driver, 'btn-success') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # 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') - move_to_element_by_class_name(driver, 'abstract-text') - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-abstract-text')) - ) + # 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)) + + # 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"]'))) + + # 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 - 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() + # Close abstract text modal + xpath_modal = '//*[@id="abstract-text-editor"]//button[@id="modal-button-ok"]' + driver.find_element(By.XPATH, xpath_modal).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(), 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') - - 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') - tc_num = element_get_attribute_by_id(driver, 'short', 'value') - driver.get("http://" + Cookies.get_host_ip() + ":9000/conference/" + tc_num + "/submission") + # 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)) - move_to_element_by_class_name(driver, 'figure') - assert len(driver.find_elements_by_class_name('figure')) == 1 + # Check figure modal is not available + assert len(driver.find_elements_by_class_name('figure')) == 0 - WebDriverWait(driver, 10).until( - EC.visibility_of_element_located((By.ID, 'button-edit-figure')) - ) - driver.find_element_by_id('button-edit-figure').click() + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]')) - ) + # 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) - assert len(driver.find_elements_by_xpath('//*[@id="figures-editor"]//div[@class="modal-body"]' - '//div[contains(@data-bind, "figures().length>=3")]')) == 1 + # Save conference settings + conftest.element_click_by_class_name(driver, 'btn-success') - driver.find_element_by_xpath('//*[@id="figures-editor"]//button[@id="modal-button-ok"]').click() + # 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') - 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 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)) - def test_groups(self): - driver = self.driver - WebDriverWait(driver, 30).until( - EC.presence_of_element_located((By.XPATH, '//li/a[contains(@href,"groups")]')) - ) + # Check figure section is available + assert len(driver.find_elements_by_class_name('figure')) == 1 - move_to_element_by_xpath(driver, '//li/a[contains(@href,"groups")]') - driver.find_element_by_xpath('//li/a[contains(@href,"groups")]').click() + # 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() - move_to_element_by_xpath(driver, '//tr[@id="newGroup"]//td/button') - driver.find_element_by_xpath('//tr[@id="newGroup"]//td/button').click() + self.wait_until(10, EC.element_to_be_clickable((By.XPATH, '//*[@id="figures-editor"]'))) - assert "Prefix, short and long entries have to be provided!" in \ - driver.find_element_by_xpath('//div[contains(@class,"alert-danger")]/strong').text + # 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 - move_to_element_by_id(driver, 'ngPrefix') - driver.find_element_by_id('ngPrefix').send_keys("u") + # Close figure modal + xpath_modal = '//*[@id="figures-editor"]//button[@id="modal-button-ok"]' + driver.find_element_by_xpath(xpath_modal).click() - move_to_element_by_id(driver, 'ngShort') - driver.find_element_by_id('ngShort').send_keys("3") + # Switch back to the conference settings page + driver.get("http://%s:9000/dashboard/conference/%s" % (Cookies.get_host_ip(), conf_id)) - move_to_element_by_id(driver, 'ngName') - driver.find_element_by_id('ngName').send_keys("3") + def test_groups(self): + driver = self.driver - 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 diff --git a/test/frontend/test_editor.py b/test/frontend/test_editor.py index 10967b84..9de8239f 100644 --- a/test/frontend/test_editor.py +++ b/test/frontend/test_editor.py @@ -8,105 +8,128 @@ @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): + """ + 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') + 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 - #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 - WebDriverWait(driver, 30).until( - EC.visibility_of_element_located((By.XPATH, '//*[@id="title-editor"]')) - ) + # 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 - WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((By.ID, 'button-action')) - ) + # 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 - WebDriverWait(driver, 30).until( - EC.text_to_be_present_in_element((By.ID, 'lblvalid'), 'issues') - ) + # 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') - 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() + # 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="authors-editor"]//button[contains(@class, "btn-add")]')) - ) - - 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() + 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") + + # 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 @@ -114,15 +137,20 @@ def test_add_author(self): def test_remove_author(self): driver = self.driver + + # Open authors modal 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() + # 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 @@ -131,239 +159,292 @@ def test_remove_author(self): def test_add_affiliations(self): driver = self.driver + + # Open affiliations modal self.click_edit_button('affiliations') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "btn-add")]')) - ) - - 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_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() + 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "btn-add")]')) - ) - - 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_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() + 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "btn-remove")]')) - ) - 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="affiliations-editor"]' - '//button[contains(@class, "button-remove-affiliation-from-author")]')) - ) - 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') - 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))) + # 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') - 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))) + + # 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) - 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() + # Close modal + xpath_btn_modal = '//*[@id="acknowledgements-editor"]//button[@id="modal-button-ok"]' + driver.find_element(By.XPATH, xpath_btn_modal).click() - assert "Thanks." in driver.find_element_by_xpath('//*[@class="acknowledgements"]/p').text + 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) + 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') + # 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"]//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")]')) - ) - - driver.find_element_by_xpath('//*[@id="references-editor"]' - '//input[contains(@class, "citation")]').send_keys("John, title.") + # 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) + # 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"]//button[contains(@class, "btn-add")]').click() + # 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"]' - '//input[contains(@class, "link")]').send_keys("www.link.com") - - 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]//button[contains(@class, "btn-add")]')) - ) - - 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() - 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))) + # 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') - WebDriverWait(driver, 10).until( - EC.element_to_be_clickable((By.XPATH, '//*[@id="references-editor"]' - '//button[contains(@class, "btn-remove")]')) - ) + 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') - 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() + # 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) 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")