galaxy_test.selenium.jupyter package

Examples and framework helpers for driving Galaxy with Selenium in Jupyter.

Example Notebooks

There are a couple example notebooks in this directory that demonstrate two different helper classes that provide a Python context for interacting with Galaxy.

notebook_example_library.ipynb demonstrates using galaxy.selenium.jupyter_context.JupyterContext, an interface that only depends on the pip installable library galaxy-selenium. JupyterContext inherits galaxy.selenium.navigates_galaxy.NavigatesGalaxy and galaxy.selenium.has_driver.HasDriver and contains numerous functions to interact with Galaxy in generic terms using Selenium.

notebook_example_testing.ipynb demonstrates using galaxy_test.selenium.jupyter_context.JupyterTestContextImpl, an interface that extends JupyterContextImpl to additionally provide testing framework populators (galaxy_test.base.populators) configured to work with the same user as is logged in with Selenium and that provide a quick way to populate the target Galaxy with testing fixtures.

The first example notebook is good for prototyping stand-alone applications that drive Galaxy, the second example notebook is setup to mirror the environment available to Selenium test cases that ship with Galaxy (e.g. galaxy_test.selenium.framework:SeleniumTestCase) and can be used for interactively developing Selenium tests for Galaxy. Additionally, it shows how can ActionChains could be accessed within Jupyter notebook.

These notebooks start with a cell that simply defines a config variable in the Python environment on a cell that is marked with metadata indicated it is “parameters”. This isn’t required at all to use the notebook iteratively, but it does provide a nice hook for executing the notebook in a parameterized way using papermill after its creation.

The second cell in both of these notebooks setup the Galaxy interaction context - either a galaxy.selenium.jupyter_context.JupyterContextImpl or galaxy_test.selenium.jupyter_context.JupyterTestContextImpl depending on the notebook. These cells use a function named init to create the desired interaction context (called gx_selenium_context in both cases).

from galaxy.selenium.jupyter_context import init
gx_selenium_context = init(config)

The optional config dictionary can be used to configure both Selenium and the Galaxy that is targeted. If config is none and the working directory Jupyter is executing inside of has a file named galaxy_selenium_context.yml - init will read that file and use it as the target configuration.

Both contexts can be configured with the following dictionary keys (either from galaxy_selenium_context.yml or using papermill).

local_galaxy_url

Galaxy URL to target during execution.

selenium_galaxy_url

Galaxy URL relative to the Selenium being used. This doesn’t need to be set unless you’re using a remote Selenium server (i.e one not running directly on localhost).

driver

If set, this should be a dictionary describing variables to send to galaxy.selenium.driver_factory.ConfiguredDriver and define how to setup the Selenium client used. Useful keys and their defaults include - browser ("auto"), remote (false), remote_host ("127.0.0.1"), remote_port (4444), headless (false).

Additionally, the testing context also allows additional configuration variables used for populating test fixtures (with populators) or by extra testing helpers (e.g. gx_selenium_context.test_login()).

admin_api_key

An API key to be used for API interactions that require an admin account.

login_email

A test account login or email address to be used for tests that require a logged in user.

login_password

The password to be used for the account referenced by login_email.

Note

Using Papermill

$ . venv/bin/activate  # first two commands only needed first time
$ pip install papermill
$ papermill galaxy_test/selenium/jupyter/notebook_example_library.ipynb  galaxy_test/selenium/jupyter/notebook_example_library_output.ipynb -y "
config: {local_galaxy_url: 'http://localhost:8081/'}
"

Developing Galaxy Test Cases Interactively with Jupyter

The Setup

Writing Selenium tests for Galaxy often involves annotating the Galaxy DOM with appropriate class and data-* attributes, so it is best to have webpack monitor client/src and rebuild as things changes and then disable building the client as Galaxy starts. This can be done by executing the follow two commands in separate terminal sessions.

$ GALAXY_SKIP_CLIENT_BUILD=1 GALAXY_RUN_WITH_TEST_TOOLS=1 sh run.sh
$ make client-watch

Copy lib/galaxy_test/selenium/jupyter/galaxy_selenium.yml.sample to lib/galaxy_test/selenium/jupyter/galaxy_selenium.yml and specify a login_email, login_password, admin_api_key to point at values suitable for your local test environment.

$ cp lib/galaxy_test/selenium/jupyter/galaxy_selenium.yml.sample lib/galaxy_test/selenium/jupyter/galaxy_selenium.yml
$ vi lib/galaxy_test/selenium/jupyter/galaxy_selenium.yml

Start Jupyter for interactive development. This requires Jupyter to be available in Galaxy’s virtual environment.

$ . venv/bin/activate  # first two commands only needed first time
$ pip install jupyter
$ make serve-selenium-notebooks

Filling out Tests

Open (or copy and open) the notebook notebook_example_testing.ipynb and start developing the test in the third notebook cell. This cell will land up being the body a test case.

Use gx_selenium_context to navigate Galaxy, setup test conditions, and verify expected behavior. Change navigation.yml to implement components and client/src to annotate the source - these changes will be picked up automatically and you can simply re-run the notebook to redo the modified or extended test. If Python test code needs to be changed (e.g. helper methods are added to galaxy.selenium.navigates_galaxy.NavigatesGalaxy), you’ll need to select “Restart & Run All” from the “Kernel” menu of Jupyter to pickup the new changes.

Once the test is complete, copy all the cells after the initialization into a new test case file (either in lib/galaxy_test/selenium or test/integration_selenium). Some examples of pull request commits developed this way include Galaxy’s initial workflow invocation detail tests and initial history import and export tests. These commits demonstrate the basics of how to turn operations on a gx_selenium_context into a Galaxy test case, how to add UI selectors to navigation.yml, how to add functionality to navigates_galaxy.py to be shared across test cases. The history import and export tests additionally are examples of both regular Selenium test cases as well as their integration-style variant that configures Galaxy before the test runs.

Much more information on structuring Selenium test cases generally, the difference between tests that should be place in lib/galaxy_test/selenium versus ones that should be placed in test/integration_selenium, and information on running Selenium test cases can all be found in Writing Tests for Galaxy.

Note

Test Case Attributes

If you’d like to simplify your test by logging into Galaxy as a pre-condition, add ensure_registered = True on the test case class. Your test case can use an admin key to populate fixtures without any extra annotation but to ensure a user logged in with ensure_registered is an admin user simply annotate your test case with requires_admin = True.