mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #10755 from mvdbeek/selenium_annotation_fix
Fix currently failing selenium tests, move to github workflow
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
name: Selenium tests
|
||||
on: [push, pull_request]
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgres://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_SKIP_FLAKEY_TESTS_ON_ERROR: 'true'
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
chunk: [0, 1, 2]
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:11
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- uses: nanasess/setup-chromedriver@master
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh -selenium lib/galaxy_test/selenium -- --num-shards=3 --shard-id=${{ matrix.chunk }}
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Selenium test results
|
||||
path: 'galaxy root/database/test_errors'
|
||||
@@ -11,10 +11,16 @@
|
||||
<b-button type="submit" variant="primary" @click="setUsername()">Set Username</b-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<b-form-checkbox switch v-model="item.importable" @change="onImportable">
|
||||
<b-form-checkbox switch class="make-accessible" v-model="item.importable" @change="onImportable">
|
||||
Make {{ model_class }} accessible.
|
||||
</b-form-checkbox>
|
||||
<b-form-checkbox v-if="item.importable" switch v-model="item.published" @change="onPublish">
|
||||
<b-form-checkbox
|
||||
v-if="item.importable"
|
||||
class="make-publishable"
|
||||
switch
|
||||
v-model="item.published"
|
||||
@change="onPublish"
|
||||
>
|
||||
Make {{ model_class }} publicly available in
|
||||
<a :href="published_url" target="_top">Published {{ plural_name }}</a> section.
|
||||
</b-form-checkbox>
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div class="tool-footer">
|
||||
<!-- <b-button v-b-toggle.collapse-about>About this tool</b-button> -->
|
||||
<b-link :aria-expanded="expanded" aria-controls="collapse-about" @click="expanded = !expanded"
|
||||
<b-link
|
||||
:aria-expanded="expanded"
|
||||
aria-controls="collapse-about"
|
||||
class="collapse-about"
|
||||
@click="expanded = !expanded"
|
||||
>About this tool
|
||||
<font-awesome-icon :icon="expanded ? 'angle-double-up' : 'angle-double-down'" />
|
||||
</b-link>
|
||||
@@ -17,6 +21,7 @@
|
||||
@click="copyBibtex"
|
||||
/>
|
||||
<Citation
|
||||
class="formatted-reference"
|
||||
v-for="(citation, index) in citations"
|
||||
:key="index"
|
||||
:citation="citation"
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<div id="workflow-annotation-area" class="mt-2">
|
||||
<b>Annotation</b>
|
||||
<meta itemprop="description" :content="annotation" />
|
||||
<b-textarea id="workflow-annotation" :value="annotation" @change="onAnnotation" />
|
||||
<b-textarea id="workflow-annotation" :value="annotation" @input="onAnnotation" />
|
||||
<div class="form-text text-muted">
|
||||
These notes will be visible when this workflow is viewed.
|
||||
</div>
|
||||
@@ -165,7 +165,12 @@ export default {
|
||||
this.onAttributes({ tags });
|
||||
},
|
||||
onAnnotation(annotation) {
|
||||
this.onAttributes({ annotation });
|
||||
if (this.annotationTimeout) {
|
||||
clearTimeout(this.annotationTimeout);
|
||||
}
|
||||
this.annotationTimeout = setTimeout(() => {
|
||||
this.onAttributes({ annotation });
|
||||
}, 300);
|
||||
},
|
||||
onRename(name) {
|
||||
this.onAttributes({ name });
|
||||
@@ -193,6 +198,9 @@ export default {
|
||||
this.onError(error);
|
||||
});
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
clearTimeout(this.annotationTimeout);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -292,6 +292,22 @@ export default {
|
||||
this.$emit("onActivate", this);
|
||||
});
|
||||
},
|
||||
setAnnotation(annotation) {
|
||||
if (this.annotationTimeout) {
|
||||
clearTimeout(this.annotationTimeout);
|
||||
}
|
||||
this.annotationTimeout = setTimeout(() => {
|
||||
this.annotation = annotation;
|
||||
}, 100);
|
||||
},
|
||||
setLabel(label) {
|
||||
if (this.labelTimeout) {
|
||||
clearTimeout(this.labelTimeout);
|
||||
}
|
||||
this.labelTimeout = setTimeout(() => {
|
||||
this.label = label;
|
||||
}, 100);
|
||||
},
|
||||
setData(data) {
|
||||
this.config_form = data.config_form;
|
||||
this.tool_state = data.tool_state;
|
||||
|
||||
@@ -116,10 +116,13 @@ function _addLabelAnnotation(self, node) {
|
||||
inputs.unshift({
|
||||
type: "text",
|
||||
name: "__annotation",
|
||||
label: "Annotation",
|
||||
label: "Step Annotation",
|
||||
fixed: true,
|
||||
value: node.annotation,
|
||||
area: true,
|
||||
onchange: function (new_annotation) {
|
||||
node.setAnnotation(new_annotation);
|
||||
},
|
||||
help: "Add an annotation or notes to this step. Annotations are available when a workflow is viewed.",
|
||||
});
|
||||
inputs.unshift({
|
||||
@@ -130,6 +133,7 @@ function _addLabelAnnotation(self, node) {
|
||||
help: _l("Add a step label."),
|
||||
fixed: true,
|
||||
onchange: function (new_label) {
|
||||
node.setLabel(new_label);
|
||||
let duplicate = false;
|
||||
for (const i in workflow.nodes) {
|
||||
const n = workflow.nodes[i];
|
||||
@@ -145,7 +149,6 @@ function _addLabelAnnotation(self, node) {
|
||||
"error_text",
|
||||
duplicate && "Duplicate label. Please fix this before saving the workflow."
|
||||
);
|
||||
self.form.trigger("change");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ pytest-html = "*"
|
||||
pytest-mock = "*"
|
||||
pytest-pythonpath = "*"
|
||||
pytest-postgresql = "*"
|
||||
pytest-shard = "*"
|
||||
recommonmark = "*"
|
||||
responses = "*"
|
||||
selenium = "*"
|
||||
|
||||
@@ -45,6 +45,7 @@ pytest-metadata==1.10.0; python_version >= '2.7' and python_version not in '3.0,
|
||||
pytest-mock==3.3.1
|
||||
pytest-postgresql==2.5.2
|
||||
pytest-pythonpath==0.7.3
|
||||
pytest-shard==0.1.1
|
||||
pytest==6.1.2
|
||||
python-irodsclient==0.8.5
|
||||
pytz==2020.4
|
||||
|
||||
@@ -113,7 +113,7 @@ def get_item_annotation_obj(db_session, user, item):
|
||||
|
||||
# Get annotation association class.
|
||||
annotation_assoc_class = _get_annotation_assoc_class(item)
|
||||
if not annotation_assoc_class:
|
||||
if not annotation_assoc_class or item.id is None:
|
||||
return None
|
||||
|
||||
# Get annotation association object.
|
||||
|
||||
@@ -216,6 +216,10 @@ class NavigatesGalaxy(HasDriver):
|
||||
def history_panel_name(self):
|
||||
return self.history_panel_name_element().text
|
||||
|
||||
def make_accessible_and_publishable(self):
|
||||
self.components.histories.sharing.make_accessible.wait_for_and_click()
|
||||
self.components.histories.sharing.make_publishable.wait_for_and_click()
|
||||
|
||||
def history_contents(self, history_id=None, view='summary', datasets_only=True):
|
||||
if history_id is None:
|
||||
history_id = self.current_history_id()
|
||||
|
||||
@@ -286,7 +286,8 @@ histories:
|
||||
selectors:
|
||||
unshare_user_button: '.unshare_user'
|
||||
share_with_a_user_button: '#share_with_a_user'
|
||||
make_accessible_and_publish: '#make_accessible_and_publish'
|
||||
make_accessible: '.make-accessible label'
|
||||
make_publishable: '.make-publishable label'
|
||||
labels:
|
||||
unshare: 'Unshare'
|
||||
|
||||
@@ -326,11 +327,8 @@ tool_form:
|
||||
options: '#options [data-toggle="dropdown"]'
|
||||
execute: 'button#execute'
|
||||
parameter_div: 'div.ui-form-element[tour_id="${parameter}"]'
|
||||
citations: '.citations-formatted'
|
||||
reference: '.citations-formatted .formatted-reference'
|
||||
show_bibtex:
|
||||
type: xpath
|
||||
selector: '//a[@class="nav-link" and text()="BibTeX"]'
|
||||
reference: '.formatted-reference'
|
||||
about: '.collapse-about'
|
||||
|
||||
labels:
|
||||
generate_tour: 'Generate Tour'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Utilities for using sizzle (jQuery-style) selectors with Selenium."""
|
||||
|
||||
import re
|
||||
import json
|
||||
|
||||
from selenium.common.exceptions import NoSuchElementException
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
@@ -119,11 +119,9 @@ def _is_sizzle_loaded(driver):
|
||||
|
||||
|
||||
def _make_sizzle_string(sizzle_selector):
|
||||
try:
|
||||
selector = sizzle_selector.decode("utf-8")
|
||||
except (AttributeError, UnicodeEncodeError):
|
||||
selector = sizzle_selector
|
||||
return "return Sizzle(\"{selector}\");".format(selector=re.escape(selector))
|
||||
# Use json.dumps to escape quotes
|
||||
selector = json.dumps(sizzle_selector)
|
||||
return f"return Sizzle({selector});"
|
||||
|
||||
|
||||
__all__ = (
|
||||
|
||||
@@ -43,7 +43,7 @@ class SavedHistoriesTestCase(SharedStateSeleniumTestCase):
|
||||
|
||||
# Publish the history
|
||||
self.click_grid_popup_option(self.history2_name, 'Share or Publish')
|
||||
self.components.histories.sharing.make_accessible_and_publish.wait_for_and_click()
|
||||
self.make_accessible_and_publishable()
|
||||
|
||||
self.navigate_to_histories_page()
|
||||
|
||||
|
||||
@@ -199,8 +199,7 @@ class HistoryGridTestCase(SharedStateSeleniumTestCase):
|
||||
|
||||
def publish_current_history(self):
|
||||
self.click_history_option('Share or Publish')
|
||||
self.components.histories.sharing.make_accessible_and_publish.wait_for_and_click()
|
||||
self.wait_for_selector_clickable('#disable_link_access_and_unpublish')
|
||||
self.make_accessible_and_publishable()
|
||||
|
||||
def navigate_to_published_histories_page(self):
|
||||
self.home()
|
||||
|
||||
@@ -124,7 +124,7 @@ class ToolFormTestCase(SeleniumTestCase, UsesHistoryItemAssertions):
|
||||
citations_api = self.api_get("tools/bibtex/citations")
|
||||
assert len(citations_api) == 29, len(citations_api)
|
||||
self.tool_open("bibtex")
|
||||
self.components.tool_form.citations.wait_for_visible()
|
||||
self.components.tool_form.about.wait_for_and_click()
|
||||
|
||||
@retry_assertion_during_transitions
|
||||
def assert_citations_visible():
|
||||
@@ -138,12 +138,6 @@ class ToolFormTestCase(SeleniumTestCase, UsesHistoryItemAssertions):
|
||||
assert "Galaxy: A platform for interactive" in doi_resolved_citation.text
|
||||
self.screenshot("tool_form_citations_formatted")
|
||||
|
||||
self.components.tool_form.show_bibtex.wait_for_and_click()
|
||||
references = assert_citations_visible()
|
||||
r0text = references[0].text
|
||||
assert "@article{Giardine_2005" in r0text
|
||||
self.screenshot("tool_form_citations_bibtex")
|
||||
|
||||
def _check_dataset_details_for_inttest_value(self, hid, expected_value="42"):
|
||||
self.hda_click_primary_action_button(hid, "info")
|
||||
|
||||
|
||||
@@ -63,9 +63,6 @@ class WorkflowEditorTestCase(SeleniumTestCase):
|
||||
editor.label_input.wait_for_and_send_keys("input1")
|
||||
editor.annotation_input.wait_for_and_send_keys("my cool annotation")
|
||||
self.sleep_for(self.wait_types.UX_RENDER)
|
||||
self.screenshot("workflow_editor_data_input_filled_in PRECLICK")
|
||||
editor.label_input.wait_for_and_click() # Seems to help force the save of whole annotation.
|
||||
self.sleep_for(self.wait_types.UX_RENDER)
|
||||
self.screenshot("workflow_editor_data_input_filled_in")
|
||||
self.workflow_editor_click_save()
|
||||
|
||||
@@ -75,7 +72,7 @@ class WorkflowEditorTestCase(SeleniumTestCase):
|
||||
label = editor.label_input.wait_for_value()
|
||||
assert label == "input1", label
|
||||
annotation = editor.annotation_input.wait_for_value()
|
||||
assert annotation == "my cool annotation"
|
||||
assert annotation == "my cool annotation", annotation
|
||||
data_input_node.destroy.wait_for_and_click()
|
||||
data_input_node.wait_for_absent()
|
||||
self.screenshot("workflow_editor_data_input_deleted")
|
||||
@@ -89,7 +86,6 @@ class WorkflowEditorTestCase(SeleniumTestCase):
|
||||
self.screenshot("workflow_editor_data_collection_input_new")
|
||||
editor.label_input.wait_for_and_send_keys("input1")
|
||||
editor.annotation_input.wait_for_and_send_keys("my cool annotation")
|
||||
editor.label_input.wait_for_and_click() # Seems to help force the save of whole annotation.
|
||||
self.sleep_for(self.wait_types.UX_RENDER)
|
||||
self.screenshot("workflow_editor_data_collection_input_filled_in")
|
||||
self.workflow_editor_click_save()
|
||||
@@ -100,7 +96,7 @@ class WorkflowEditorTestCase(SeleniumTestCase):
|
||||
label = editor.label_input.wait_for_value()
|
||||
assert label == "input1", label
|
||||
annotation = editor.annotation_input.wait_for_value()
|
||||
assert annotation == "my cool annotation"
|
||||
assert annotation == "my cool annotation", annotation
|
||||
data_input_node.destroy.wait_for_and_click()
|
||||
data_input_node.wait_for_absent()
|
||||
self.sleep_for(self.wait_types.UX_RENDER)
|
||||
@@ -115,7 +111,6 @@ class WorkflowEditorTestCase(SeleniumTestCase):
|
||||
self.screenshot("workflow_editor_parameter_input_new")
|
||||
editor.label_input.wait_for_and_send_keys("input1")
|
||||
editor.annotation_input.wait_for_and_send_keys("my cool annotation")
|
||||
editor.label_input.wait_for_and_click() # Seems to help force the save of whole annotation.
|
||||
self.sleep_for(self.wait_types.UX_RENDER)
|
||||
self.screenshot("workflow_editor_parameter_input_filled_in")
|
||||
self.workflow_editor_click_save()
|
||||
@@ -126,7 +121,7 @@ class WorkflowEditorTestCase(SeleniumTestCase):
|
||||
label = editor.label_input.wait_for_value()
|
||||
assert label == "input1", label
|
||||
annotation = editor.annotation_input.wait_for_value()
|
||||
assert annotation == "my cool annotation"
|
||||
assert annotation == "my cool annotation", annotation
|
||||
data_input_node.destroy.wait_for_and_click()
|
||||
data_input_node.wait_for_absent()
|
||||
self.sleep_for(self.wait_types.UX_RENDER)
|
||||
@@ -146,16 +141,16 @@ steps:
|
||||
inttest: input_int
|
||||
""")
|
||||
self.screenshot("workflow_editor_parameter_connection_simple")
|
||||
self.assert_connected("input_int#output", "simple_constructs#inttest")
|
||||
self.assert_connected("input_int#output", "tool_exec#inttest")
|
||||
|
||||
editor = self.components.workflow_editor
|
||||
|
||||
tool_node = editor.node._(label="simple_constructs")
|
||||
tool_node = editor.node._(label="tool_exec")
|
||||
tool_input = tool_node.input_terminal(name="inttest")
|
||||
tool_input.wait_for_and_click()
|
||||
|
||||
editor.connector_destroy_callout.wait_for_and_click()
|
||||
self.assert_not_connected("input_int#output", "simple_constructs#inttest")
|
||||
self.assert_not_connected("input_int#output", "tool_exec#inttest")
|
||||
self.screenshot("workflow_editor_parameter_connection_destroyed")
|
||||
|
||||
# When connected, cannot turn it into a RuntimeValue..
|
||||
@@ -177,8 +172,8 @@ steps:
|
||||
tool_input.wait_for_visible()
|
||||
collapse_input.wait_for_absent_or_hidden()
|
||||
|
||||
self.workflow_editor_connect("input_int#output", "simple_constructs#inttest", screenshot_partial="workflow_editor_parameter_connection_dragging")
|
||||
self.assert_connected("input_int#output", "simple_constructs#inttest")
|
||||
self.workflow_editor_connect("input_int#output", "tool_exec#inttest", screenshot_partial="workflow_editor_parameter_connection_dragging")
|
||||
self.assert_connected("input_int#output", "tool_exec#inttest")
|
||||
|
||||
@selenium_test
|
||||
def test_existing_connections(self):
|
||||
|
||||
+3
-3
@@ -393,7 +393,7 @@ do
|
||||
;;
|
||||
-selenium|--selenium)
|
||||
GALAXY_TEST_TOOL_CONF="lib/galaxy/config/sample/tool_conf.xml.sample,test/functional/tools/samples_tool_conf.xml"
|
||||
test_script="./scripts/functional_tests.py"
|
||||
test_script="pytest"
|
||||
report_file="./run_selenium_tests.html"
|
||||
skip_client_build=""
|
||||
selenium_test=1;
|
||||
@@ -617,8 +617,8 @@ setup_python
|
||||
if [ -n "$framework_test" -o -n "$installed_test" -o -n "$migrated_test" -o -n "$data_managers_test" ] ; then
|
||||
[ -n "$test_id" ] && selector="-k $test_id" || selector=""
|
||||
extra_args="test/functional/test_toolbox_pytest.py $selector $marker"
|
||||
elif [ -n "$selenium_test" ] ; then
|
||||
extra_args="$selenium_script -selenium"
|
||||
elif [ -n "$selenium_script" ]; then
|
||||
extra_args="$selenium_script"
|
||||
elif [ -n "$toolshed_script" ]; then
|
||||
extra_args="$toolshed_script"
|
||||
elif [ -n "$api_script" ]; then
|
||||
|
||||
Reference in New Issue
Block a user