Merge pull request #13993 from jmchilton/workflow_jest_tests

More workflow Jest tests.
This commit is contained in:
John Chilton
2022-06-03 08:53:36 -04:00
committed by GitHub
7 changed files with 1084 additions and 922 deletions
@@ -4,6 +4,7 @@ import { getLocalVue } from "jest/helpers";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import flushPromises from "flush-promises";
import { ROOT_COMPONENT } from "utils/navigation";
const localVue = getLocalVue(true);
@@ -41,8 +42,8 @@ describe("WorkflowDropdown.vue", () => {
});
it("should not display source metadata if not present", async () => {
expect(wrapper.find(".workflow-trs-icon").exists()).toBeFalsy();
expect(wrapper.find(".workflow-external-link").exists()).toBeFalsy();
expect(wrapper.find(ROOT_COMPONENT.workflows.trs_icon.selector).exists()).toBeFalsy();
expect(wrapper.find(ROOT_COMPONENT.workflows.external_link.selector).exists()).toBeFalsy();
});
it("should display name and description", async () => {
@@ -1,10 +1,11 @@
import WorkflowIndexActions from "./WorkflowIndexActions";
import { shallowMount } from "@vue/test-utils";
import { getLocalVue } from "jest/helpers";
import { ROOT_COMPONENT } from "utils/navigation";
import "jest-location-mock";
const localVue = getLocalVue();
const localVue = getLocalVue(true);
describe("WorkflowIndexActions.vue", () => {
let wrapper;
@@ -21,13 +22,18 @@ describe("WorkflowIndexActions.vue", () => {
describe("naviation", () => {
it("should create a workflow when create is clicked", async () => {
await wrapper.find("#workflow-create").trigger("click");
await wrapper.find(ROOT_COMPONENT.workflows.new_button.selector).trigger("click");
expect(window.location).toBeAt("/root/workflows/create");
});
it("should import a workflow when create is clicked", async () => {
await wrapper.find("#workflow-import").trigger("click");
await wrapper.find(ROOT_COMPONENT.workflows.import_button.selector).trigger("click");
expect(window.location).toBeAt("/root/workflows/import");
});
it("should localize button text", async () => {
expect(wrapper.find(ROOT_COMPONENT.workflows.new_button.selector).text()).toBeLocalizationOf("Create");
expect(wrapper.find(ROOT_COMPONENT.workflows.import_button.selector).text()).toBeLocalizationOf("Import");
});
});
});
@@ -0,0 +1,29 @@
import WorkflowRunButton from "./WorkflowRunButton";
import { shallowMount } from "@vue/test-utils";
import { getLocalVue } from "jest/helpers";
import { ROOT_COMPONENT } from "utils/navigation";
import "jest-location-mock";
const localVue = getLocalVue(true);
const WORKFLOW_ID = "workflow_id123";
describe("WorkflowRunButton.vue", () => {
let wrapper;
beforeEach(async () => {
const propsData = {
root: "/root/",
id: WORKFLOW_ID,
};
wrapper = shallowMount(WorkflowRunButton, {
propsData,
localVue,
});
});
it("should localize title text", async () => {
const selector = ROOT_COMPONENT.workflows.run_button({ id: WORKFLOW_ID }).selector;
expect(wrapper.find(selector).attributes("title")).toBeLocalizationOf("Run workflow");
});
});
@@ -2,6 +2,7 @@
<b-button
v-b-tooltip.hover.bottom
:title="title | localize"
:data-workflow-run="id"
class="workflow-run btn-sm btn-primary fa fa-play"
@click.stop="executeWorkflow" />
</template>
+123
View File
@@ -0,0 +1,123 @@
import NAVIGATION_DATA from "./navigation.yml";
function interpolate(template, properties) {
let parsed = template;
Object.keys(properties).forEach((key) => {
const value = properties[key];
parsed = parsed.replace("${" + key + "}", value);
});
return parsed;
}
class SelectorTemplate extends Function {
constructor(selector, selectorType, props = {}, children = {}) {
super();
if (selectorType == "data-description") {
selectorType = "css";
selector = `[data-description="${selector}"]`;
}
this._selector = selector;
this.selectorType = selectorType;
this._props = props || {};
return new Proxy(this, {
apply: (target, thisArg, args) => target._call(args),
});
}
_call(args) {
const inputProps = args[0];
const allProps = { ...this._props, ...inputProps };
return new SelectorTemplate(this._selector, this.selectorType, allProps, this.children);
}
get description() {
const selector = this.selector;
let desc;
if (this.selectorType == "css") {
desc = `CSS selector [${selector}]`;
} else if (this.selectorType == "xpath") {
desc = `XPATH selector [${selector}]`;
} else if (this.selectorType == "id") {
desc = `DOM element with id [${selector}]`;
}
return desc;
}
get selector() {
return interpolate(this._selector, this._props);
}
}
function selectorTemplateFromObject(object, children = {}) {
if (typeof object === "string" || object instanceof String) {
const selector = object;
return new SelectorTemplate(selector, "css", {}, children);
} else {
const selectorType = object.type || "css";
const selector = object.selector;
return new SelectorTemplate(selector, selectorType, {}, children);
}
}
function componentFromObject(name, object) {
const selectors = {};
const subComponents = {};
Object.keys(object).forEach((key) => {
const value = object[key];
if (key == "selectors") {
let baseSelector = null;
const hasBaseSelector = value["_"] !== undefined;
if (hasBaseSelector) {
baseSelector = value["_"];
delete value["_"];
}
Object.keys(value).forEach((selectorKey) => {
const selectorValue = value[selectorKey];
if (selectorValue == undefined) {
throw `Problem with selectors value ${selectorValue}`;
}
selectors[selectorKey] = selectorTemplateFromObject(selectorValue);
});
if (baseSelector) {
selectors["_"] = selectorTemplateFromObject(baseSelector, selectors);
}
} else if (key == "labels") {
// implement as needed
} else if (key == "text") {
// implement as needed
} else {
const component = componentFromObject(key, value);
subComponents[key] = component;
}
});
return new Component(name, subComponents, selectors);
}
class Component {
constructor(name, subComponents, selectors) {
self._name = name;
self._subComponents = subComponents;
self._selectors = selectors;
const component = this;
Object.keys(subComponents).forEach((key) => {
const value = subComponents[key];
component[key] = value;
});
Object.keys(selectors).forEach((key) => {
const value = selectors[key];
component[key] = value;
});
}
get selector() {
if (hasOwnProperty("_")) {
return this["_"];
} else {
throw `No _ selector for [${this}]`;
}
}
}
export const ROOT_COMPONENT = componentFromObject("root", NAVIGATION_DATA);
+918
View File
@@ -0,0 +1,918 @@
# top_level: {global: <components>, workflows: <components>, histories: <components>}
# components := {<subcomponent_name>: <components>} | <component>
# component := {selectors: <selectors_map>, labels: <labels_map>, ids: <id_map>}
# selectors_map := {<selector_name>: <selector>}
# selector := <str> | {type: <selector_type>, selector: <str>}
# selector_type := css|xpath|sizzle|id
# labels_map := {<label_name>: <label>}
_: # global stuff
selectors:
editable_text: '.editable-text'
tooltip_balloon: '.tooltip'
left_panel_drag: '#left > .unified-panel-footer > .drag'
left_panel_collapse: '#left > .unified-panel-footer > .panel-collapse'
right_panel_drag: '#right > .unified-panel-footer > .drag'
right_panel_collapse: '#right > .unified-panel-footer > .panel-collapse'
by_attribute: '${scope} [${name}="${value}"]'
messages:
selectors:
all: '[class*="alert"]'
error: '.alert-danger'
warning: '.alert-warning'
done: '.alert-success'
info: '.alert-info'
donelarge: '.donemessagelarge'
infolarge: '.infomessagelarge'
require_login: 'a.require-login-link'
masthead:
selectors:
_: '#masthead'
# bootstrap-vue a tag doesn't work as link target, need to hit span inside
user: '#user.loggedin-only > a.nav-link.dropdown-toggle > span'
register_or_login: '#user.loggedout-only > .nav-link'
user_menu: '#user .dropdown-menu a'
workflow: '#workflow .nav-link'
username:
type: xpath
selector: '//a[contains(text(), "Logged in as")]'
logged_in_only: '.loggedin-only'
logged_out_only: '.loggedout-only'
labels:
# top-level menus
analyze: 'Analyze Data'
workflow: 'Workflow'
shared_data: 'Shared Data'
visualization: 'Visualization'
help: 'Help'
user: 'User'
admin: 'Admin'
# user menu
logout: 'Logout'
custom_builds: 'Custom Builds'
preferences: 'Preferences'
histories: 'Histories'
invocations: 'Workflow Invocations'
pages: 'Pages'
# Shared data
libraries: 'Data Libraries'
published_histories: 'Histories'
preferences:
selectors:
sign_out: "#edit-preferences-sign-out"
change_password: "#edit-preferences-password"
manage_information: '#edit-preferences-information'
toolbox_filters: '#edit-preferences-toolbox-filters'
manage_api_key: '#edit-preferences-api-key'
current_email: "#user-preferences-current-email"
get_new_key: '#submit'
delete_account: '#delete-account'
delete_account_input: '#name-input'
delete_account_ok_btn: '.modal-footer .btn-primary'
toolbox_filters:
selectors:
input:
type: xpath
selector: "//span[contains(., '${description}')]/../div/div/label[@class='custom-control-label']"
submit: '#submit'
change_user_email:
selectors:
submit: '#submit'
change_user_password:
selectors:
submit: '#submit'
change_user_address:
selectors:
address_button:
type: xpath
selector: '//span[contains(text(), "Insert Address")]'
sign_out:
selectors:
cancel_button: '.modal-footer .buttons #button-0'
sign_out_button: '.modal-footer .buttons #button-1'
dataset_details:
selectors:
_: 'table#dataset-details'
tool_parameters: 'table#tool-parameters'
transform_action: '[data-transform-action="${action}"]'
deferred_source_uri: '.deferred-dataset-source-uri'
history_panel:
menu:
labels:
new: 'Create New'
item:
selectors:
# These now appear other places :_( - e.g. in the invocation view so we'll try
# prefixing ids with #current-history-panel but obviously we need to switch to classes or data
_: '#current-history-panel #${history_content_type}-${id}'
title: '${_} .content-title'
hid: '${_} .hid'
name: '${_} .name'
details: '${_} .details'
title_button_area: '${_} .primary-actions'
primary_action_buttons: '${_} .actions .left'
secondary_action_buttons: '${_} .actions .right'
summary: '${_} .summary'
blurb: '${_} .blurb .value'
dbkey: '${_} .dbkey .value'
info: '${_} .info .value'
peek: '${_} .dataset-peek'
toolhelp_title: '${_} .toolhelp strong'
# Title buttons...
display_button: '${_} .display-btn'
edit_button: '${_} .edit-btn'
delete_button: '${_} .delete-btn'
# Action buttons...
download_button: '${_} .icon-btn.download-btn'
info_button: '${_} .icon-btn.params-btn'
tool_help_button: '${_} .fa.fa-question'
rerun_button: '${_} .icon-btn.rerun-btn'
alltags: '${_} .alltags .ti-tags'
# beta content item
content_item:
selectors:
# specific rows selectable with attributes via suffix
_: '.history-index .content-item${suffix}'
title: '${_} .content-title'
details: '${_} .details'
summary: '${_} .summary'
hid: '${_} .hid'
name: '${_} .name'
blurb: '${_} .blurb .value'
dbkey: '${_} .dbkey .value'
info: '${_} .info .value'
peek: '${_} .dataset-peek'
toolhelp_title: '${_} .toolhelp strong'
# Title buttons...
display_button: '${_} .display-btn'
edit_button: '${_} .edit-btn'
delete_button: '${_} .delete-btn'
rerun_button: '${_} .rerun-btn'
# Action buttons...
download_button: '${_} .download-btn'
info_button: '${_} .params-btn'
alltags: '${_} .alltags .ti-tags'
dataset_operations_dropdown: '${_} .dataset-actions'
# re-usable history editor, scoped for use in different layout scenarios (multi, etc.)
editor:
selectors:
_: '${scope} [data-description="edit details"]'
name: '${_} [data-description="name display"]'
toggle: '${_} [data-description="editor toggle"]'
form: '${_} [data-description="edit form"]'
name_input: '${_} [data-description="name input"]'
annotation_input: '${_} [data-description="annotation input"]'
tags_input: '${_} .tags input'
save_button: '${_} [data-description="editor save button"]'
# beta history tags
tag_editor:
selectors:
_: '${scope} .details .tags'
toggle: '${_} .toggle-link'
display: '${_} .tag-area .tag-name'
input: '${_} input'
tag_area: '${_} .tag-area'
tag_close_btn: '${_} .ti-icon-close'
multi_operations:
selectors:
show_button: '.show-history-content-selectors-btn'
action_button: '.history-contents-list-action-menu-btn'
action_menu: '.list-action-menu .dropdown-menu'
labels:
build_pair: "Build Dataset Pair"
build_list: "Build Dataset List"
build_list_pairs: "Build List of Dataset Pairs"
build_from_rules: "Build Collection from Rules"
collection_view:
selectors:
_: '.dataset-collection-panel'
nav_menu: '[data-description="collection breadcrumbs menu"]'
back_button: '[data-description="collection breadcrumbs menu"] :last'
back: '.navigation .back'
title: '.dataset-collection-panel .controls .title .editable-text'
title_input: '.dataset-collection-panel .controls .title input'
subtitle: '.dataset-collection-panel .controls .title .subtitle'
elements_warning: '.dataset-collection-panel .controls .elements-warning'
tag_area_input: '.controls .tags-display .tags-input input'
list_items: '.dataset-collection-panel .list-items .list-item'
list_items_beta: '.dataset-collection-panel .listing .content-item'
selectors:
beta: '.history-index'
legacy: '.list-panel'
_: '#current-history-panel'
search: '#current-history-panel input.search-query'
refresh_button: '.history-refresh-button'
name: '.title .name'
name_beta: '.history-title span:last-child'
name_edit_input:
selector: 'name input'
type: data-description
contents: '#current-history-panel .history-content'
contents_beta: '.history-index .content-item'
empty_message: '.empty-message'
size: '.history-size'
tag_icon: '.actions .history-tag-btn'
tag_area: '.details .tags-display'
tag_area_input: '.details .tags-display .tags-input input'
tag_close_btn: '.tags-display .ti-icon-close'
tags: 'li.ti-tag.ti-valid .tag-name'
annotation_icon: '.actions .history-annotate-btn'
annotation_area: '.details .history-annotation'
annotation_editable_text:
selector: 'annotation value'
type: data-description
annotation_edit:
selector: 'annotation input'
type: data-description
annotation_done: '.details .history-annotation .annotation button'
options_button: '[data-description="history options"]'
options_button_icon: '.details .menu-expand-button'
options_button_icon_beta: '[data-description="history options"] button'
options_button_copy_datasets_beta: '.copy-datasets-menu-item'
options_menu: '.history-options-button-menu'
options_menu_item:
type: sizzle
selector: '.history-options-button-menu > a:contains("${option_label}")'
options_show_history_structure:
type: xpath
selector: '//a[contains(text(), "Show Structure")]'
options_show_export_history_to_file: 'a[data-description="export to file"]'
options_use_beta_history:
type: xpath
selector: '//a[text()="Use Beta History Panel"]'
options_use_legacy_history: 'a[data-description="switch to legacy history view"]'
collection_menu_button: '.collection-menu'
collection_menu_edit_attributes:
type: xpath
selector: '//button[@title="Edit attributes"]'
new_history_button: '.history-new-button'
multi_view_button: '.history-view-multi-button'
histories_operation_menu: '[data-description="history options"]'
multi_view_button_beta: '[data-description="switch to multi history view"]'
pagination_pages: '.list-pagination .pages'
pagination_pages_options: '.list-pagination .pages option'
pagination_pages_selected_option: '.list-pagination .pages option:checked'
pagination_next: '.list-pagination button.next'
pagination_previous: '.list-pagination button.prev'
text:
tooltip_name: 'Rename history...'
new_name: 'Unnamed history'
history_structure:
selectors:
_: '.tool'
header: '.tool > .header.clickable'
dataset: '.tool div.list-item.dataset.history-content'
details: '.tool .details'
edit_dataset_attributes:
selectors:
database_build_dropdown: '[data-label="Database/Build"]'
save_btn: '#dataset-attributes-default-save'
dbkey_dropdown_results:
selectors:
_: '#select2-drop > .select2-results'
dbkey_dropdown_option:
type: xpath
selector: '//li[normalize-space() = "${dbkey_text}"]'
edit_collection_attributes:
selectors:
database_genome_tab:
type: xpath
selector: '//a[contains(text(), "Database/Build")]'
database_value:
type: xpath
selector: '//span[contains(text(), "${dbkey}")]'
save_btn: '.save-collection-edit'
tool_panel:
selectors:
tool_link: 'a[href$$="tool_runner?tool_id=${tool_id}"]'
outer_tool_link: '.toolTitle a[href$$="tool_runner?tool_id=${tool_id}"]'
search: '.search-query'
workflow_names: '#internal-workflows .toolTitle'
views_button: '.tool-panel-dropdown'
views_menu_item: '[data-panel-id="${panel_id}"]'
panel_labels: '.tool-panel-label'
multi_history_view:
selectors:
_: '.multi-panel-history'
item: '.multi-panel-history #${history_content_type}-${id}'
histories: '.middle .history-column'
current_label: '.current-label'
create_new_button: '.create-new'
drag_drop_help: '.history-drop-target-help'
switch_history: '.switch-to'
history_dropdown_btn: '[history-dropdown-btn="${history_id}"]'
copy: '.copy-history'
delete: '.copy-history'
current_history_check: '#history-column-${history_id} .current-label'
empty_message_check: '.empty-message'
switch_button: '#history-column-${history_id} .switch-to'
history_dropdown_menu:
selectors:
_: '[history-dropdown-menu="${history_id}"]'
delete: '[history-dropdown-menu="${history_id}"] > .delete-history'
purge: '[history-dropdown-menu="${history_id}"] > .purge-history'
copy_history_modal:
selectors:
_: '.modal-dialog'
copy_btn:
type: xpath
selector: '//button[contains(text(), "Copy")]'
history_copy_elements:
selectors:
# Following two don't really work as CSS would only work as jQuery/sizzle I think
# since the page is dynamically generated.
# https://stackoverflow.com/questions/10645552/is-it-possible-to-use-an-input-value-attribute-as-a-css-selector
dataset_checkbox: "input[id='dataset|${id}']"
collection_checkbox: 'input[id="dataset_collection|${id}"]'
new_history_name: '#new_history_name'
copy_button: "input[type='submit']"
done_link: '.donemessage a'
collection_builders:
selectors:
clear_filters: "a.clear-filters-link"
forward_datasets: ".forward-column .column-datasets"
reverse_datasets: ".reverse-column .column-datasets"
histories:
labels:
import_button: 'Import history'
sharing:
selectors:
unshare_user_button: '.share_with_view .multiselect__tag-icon'
unshare_with_user_button: '.share_with_view [data-email="${email}"] .multiselect__tag-icon'
user_email_input: '.user-email-input-form'
submit_sharing_with: '.submit-sharing-with'
share_with_collapse: '.share-with-collapse'
share_with_multiselect: '.share_with_view > .multiselect'
share_with_input: '.share_with_view input'
make_accessible: '.make-accessible label'
make_publishable: '.make-publishable label'
labels:
unshare: 'Unshare'
files_dialog:
selectors:
ftp_label: 'a[title="label-gxftp://"]'
ftp_details: 'span[title="details-gxftp://"]'
row: 'span[title="label-${uri}"]'
back_btn: '#back-btn'
history_export:
selectors:
export_link: '.export-link'
running: '.history-export-component .loading-icon'
generated_export_link: '.generated-export-link'
copy_export_link: '.copy-export-link'
show_job_link: '.show-job-link'
job_table: '.info_data_table'
job_table_ok: '.job-information-modal .btn-primary'
tab_export_to_file: '.tab-export-to-file'
directory_input: '.directory-form-input'
name_input: '.export-to-remote-file #name'
export_button: '.export-button'
success_message: '.history-export-component .alert-success'
history_import:
selectors:
radio_button_remote_files: '.history-import-component .fa-folder-open'
import_button: '.import-button'
running: '.history-import-component .loading-icon'
success_message: '.history-import-component .alert-success'
pages:
selectors:
create: '.manage-table-actions .action-button'
submit: '#submit'
export: '.markdown-pdf-export'
editor:
selectors:
wym_iframe: 'div.wym_iframe iframe'
wym_iframe_content: '.text-content'
save: '#save-button'
embed_button: '#embed-galaxy-object'
dataset_selector: '.saved-datasets'
embed_dialog_add_button: '.pages-embed .buttons #button-0'
markdown_editor: '.markdown-textarea'
labels:
embed_dataset: 'Embed Dataset'
login:
selectors:
form: 'form#login'
submit:
type: xpath
selector: "//button[@name='login']"
registration:
selectors:
toggle: '#register-toggle'
form: 'form#registration'
submit:
type: xpath
selector: "//button[@name='create']"
tool_form:
selectors:
options: '.tool-dropdown'
execute: 'button#execute'
parameter_div: 'div.ui-form-element[id="form-element-${parameter}"]'
parameter_checkbox: 'div.ui-form-element[id="form-element-${parameter}"] .ui-switch div'
parameter_input: 'div.ui-form-element[id="form-element-${parameter}"] .ui-input'
parameter_textarea: 'div.ui-form-element[id="form-element-${parameter}"] textarea'
reference: '.formatted-reference'
about: '.tool-footer'
labels:
generate_tour: 'Generate Tour'
workflows:
selectors:
new_button: '#workflow-create'
import_button: '#workflow-import'
save_button: '#workflow-save-button'
search_box: "#workflow-search"
workflow_table: "#workflow-table"
workflow_rows: "#workflow-table > tbody > tr:not(.b-table-empty-row, [style*='display: none'])"
external_link: '.workflow-external-link'
trs_icon: '.workflow-trs-icon'
pager: '.gx-workflows-grid-pager'
pager_page: '.gx-workflows-grid-pager .gx-grid-pager-page [aria-posinset=${page}]'
pager_page_next: '.gx-workflows-grid-pager .gx-grid-pager-next button'
pager_page_first: '.gx-workflows-grid-pager .gx-grid-pager-first button'
pager_page_last: '.gx-workflows-grid-pager .gx-grid-pager-last button'
pager_page_previous: '.gx-workflows-grid-pager .gx-grid-pager-prev button'
pager_page_active: '.gx-workflows-grid-pager .gx-grid-pager-page.active button'
run_button: '[data-workflow-run*="${id}"]'
trs_search:
selectors:
search: "#trs-search-query"
search_result:
type: xpath
selector: "//td[contains(text(), '${workflow_name}')]"
import_button: ".workflow-import"
select_server_button: "#dropdownTrsServer"
import_version: '[data-version-name*="${version}"]'
select_server:
type: xpath
selector: "//a[contains(@class, 'dropdown-item') and text() = '${server}']"
trs_import:
selectors:
input: "#trs-id-input"
# *= means attribute value contains "${version}"
# needed because dockstore uses branch or git tag, while workflowhub
# concatenates name and version
import_version: '[data-version-name*="${version}"]'
select_server_button: "#dropdownTrsServer"
select_server:
type: xpath
selector: "//a[contains(@class, 'dropdown-item') and text() = '${server}']"
workflow_run:
selectors:
warning: ".ui-form-composite .alert-warning"
input_div: "[step-label='${label}']"
input_data_div: "[step-label='${label}'] .select2-container"
# TODO: put step labels in the DOM ideally
subworkflow_step_icon: ".portlet-title-icon.fa-sitemap"
run_workflow: "#run-workflow"
validation_error: ".validation-error"
expand_form_link: '.workflow-expand-form-link'
expanded_form: '.workflow-expanded-form'
new_history_target_link: '.workflow-new-history-target-link'
runtime_setting_button: '.workflow-run-settings'
runtime_setting_target: '.workflow-run-settings-target'
input_select_field:
type: xpath
selector: '//div[@data-label="${label}"]//span[@class="select2-chosen"]'
workflow_editor:
node:
selectors:
_: "[node-label='${label}']"
title: '${_} .node-title'
destroy: '${_} .node-destroy'
clone: '${_} .node-clone'
output_terminal: "${_} [output-name='${name}']"
input_terminal: "${_} [input-name='${name}']"
input_mapping_icon: "${_} [input-name='${name}'].multiple"
selectors:
canvas_body: '#workflow-canvas'
edit_annotation: '#workflow-annotation'
edit_name: '#workflow-name'
tool_menu: '.toolMenuContainer'
tool_menu_section_link: '.tool-menu-section-${section_name} a span'
tool_menu_item_link: 'a.tool-menu-item-${item_name}'
workflow_link:
type: xpath
selector: '//a[contains(., "${workflow_title}")]'
connect_icon: 'div.ui-form-element[id="form-element-${name}"] .ui-form-connected-icon'
collapse_icon: 'div.ui-form-element[id="form-element-${name}"] .ui-form-collapsible-icon'
node_title:
type: xpath
selector: '//span[@class="node-title" and text()="${title}"]'
label_input:
type: xpath
selector: >
//div[@id='form-element-__label' and not(ancestor::div[contains(@style,'display: none')])]//input
annotation_input:
type: xpath
selector: >
//div[@id='form-element-__annotation' and not(ancestor::div[contains(@style,'display: none')])]//textarea
configure_output:
type: xpath
selector: >
//b[text()="Configure Output: '${output}'"]
label_output:
type: xpath
selector: >
//div[@id='form-element-__label__${output}' and not(ancestor::div[contains(@style,'display: none')])]//input
rename_output:
type: xpath
selector: >
//div[@data-label='Rename dataset']//input
change_datatype:
type: xpath
selector: >
//div[@data-label='Change datatype' and not(ancestor::div[contains(@style,'display: none')])]//span[contains(@class, 'select2-chosen')]
select_dataype_text_search:
type: xpath
selector: >
//div[@class="select2-search" and not(ancestor::div[contains(@style,'display: none')])]//input
select_datatype:
type: xpath
selector: >
//div[@class="select2-result-label" and contains(text(), "${datatype}") and not(ancestor::div[contains(@style,'display: none')])]
add_tags:
type: xpath
selector: >
//div[@data-label='Add Tags' and not(ancestor::div[contains(@style,'display: none')])]//input
remove_tags:
type: xpath
selector: >
//div[@data-label='Remove Tags' and not(ancestor::div[contains(@style,'display: none')])]//input
tool_version_button: ".tool-versions"
connector_for: "div[output-handle-id='${source_id}'][input-handle-id='${sink_id}']"
connector_destroy_callout: '.delete-terminal'
save_button: '.editor-button-save'
state_modal_body: '.state-upgrade-modal'
modal_button_continue: '.modal-footer .btn'
workflow_show:
selectors:
title: 'h3.item_name'
annotation: '.page-item-header .annotation'
invocations:
selectors:
invocations_table: '.invocations-list table'
invocations_table_rows: '.invocations-list table tbody tr:not(.b-table-empty-row, [style*="display: none"])'
pager: '.gx-invocations-grid-pager'
pager_page: '.gx-invocations-grid-pager .gx-grid-pager-page [aria-posinset=${page}]'
pager_page_next: '.gx-invocations-grid-pager .gx-grid-pager-next button'
pager_page_last: '.gx-invocations-grid-pager .gx-grid-pager-last button'
pager_page_first: '.gx-invocations-grid-pager .gx-grid-pager-first button'
pager_page_previous: '.gx-invocations-grid-pager .gx-grid-pager-prev button'
pager_page_active: '.gx-invocations-grid-pager .gx-grid-pager-page.active button'
state_details: '.workflow-invocation-state-component'
toggle_invocation_details: '.toggle-invocation-details'
progress_steps_note: '.workflow-invocation-state-component .steps-progress .progressNote'
progress_jobs_note: '.workflow-invocation-state-component .jobs-progress .progressNote'
input_details: '.workflow-invocation-state-component .invocation-inputs-details'
input_details_title: '.workflow-invocation-state-component .invocation-inputs-details [data-label="${label}"]'
input_details_name: '.workflow-invocation-state-component .invocation-inputs-details [data-label="${label}"] .name'
steps_details: '.workflow-invocation-state-component .invocation-steps-details'
step_title: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .step-title'
step_details: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .portlet-operations'
step_output_collection: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-output-collection-details'
step_output_collection_toggle: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-output-collection-details .name'
step_output_collection_element_identifier:
type: xpath
selector: '//span[@class="content-title name"][text()="${element_identifier}"]'
step_output_collection_element_datatype: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-output-collection-details .datatype .value'
step_job_details: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details'
step_job_table: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table'
step_job_table_rows: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table tbody tr'
step_job_information: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table tbody .b-table-details .info_data_table'
step_job_information_tool_id: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table tbody .b-table-details .info_data_table #galaxy-tool-id'
tour:
popover:
selectors:
_: '.tour-element'
title: '${_} .tour-title'
content: '${_} .tour-content'
next: '${_} .tour-next'
end: '${_} .tour-end'
admin:
allowlist:
selectors:
toolshed:
type: xpath
selector: '//a[contains(text(), "Toolshed Tools")]'
local:
type: xpath
selector: '//a[contains(text(), "Local Tools")]'
sanitized:
type: xpath
selector: '//a[contains(text(), "HTML Sanitized")]'
rendered_active:
type: xpath
selector: '//div[contains(@class, "active")]//a[contains(text(), "HTML Rendered")]'
manage_dependencies:
selectors:
dependencies: 'a[contains(text(), "Dependencies")]'
containers: 'a[contains(text(), "Containers")]'
unused: 'a[contains(text(), "Unused")]'
resolver_type: '#manage-resolver-type'
container_type: '#manage-container-type'
unused_paths: '#unused-paths-table'
manage_jobs:
selectors:
job_lock: '#prevent-job-dispatching'
job_lock_label:
type: xpath
selector: "//label[@for='prevent-job-dispatching']/strong"
cutoff: '#cutoff'
toolshed:
selectors:
repo_search: '#toolshed-repo-search'
search_results: '#shed-search-results'
upgrade_notification: '#repository-table .badge'
index:
selectors:
datatypes: '#admin-link-datatypes'
dependencies: '#admin-link-manage-dependencies'
data_tables: '#admin-link-data-tables'
display_applications: '#admin-link-display-applications'
errors: '#admin-link-error-stack'
forms: '#admin-link-forms'
jobs: '#admin-link-jobs'
local_data: '#admin-link-local-data'
metadata: '#admin-link-metadata'
tool_versions: '#admin-link-tool-versions'
toolshed: '#admin-link-toolshed'
users: '#admin-link-users'
quotas: '#admin-link-quotas'
groups: '#admin-link-groups'
roles: '#admin-link-roles'
impersonate: '#admin-link-impersonate'
allowlist: '#admin-link-allowlist'
selectors:
warning: '#center .alert-warning'
# TODO: place betters IDS or something on this in these grids in the DOM
jobs_title: '#jobs-title'
datatypes_grid: '#data-types-grid'
data_tables_grid: '#data-tables-grid'
display_applications_grid: '#display-applications-grid'
update_jobs: 'form[name="jobs"]'
dm_title: '#data-managers-title'
dm_data_managers_card: '#data-managers-card'
dm_jobs_button: '#${data_manager}-jobs'
dm_jobs_breadcrumb: '#breadcrumb'
dm_jobs_table: '#jobs-table'
dm_job: '#job-${job_id}'
dm_job_breadcrumb: '#breadcrumb'
dm_job_data_manager_card: '#data-manager-card'
dm_job_data_card: '#data-card-${hda_index}'
dm_table_button: '#${data_table}-table'
dm_table_card: '#data-table-card'
users_grid: '#users-grid'
users_grid_create_button: '.manage-table-actions .action-button'
groups_grid_create_button: '.manage-table-actions .action-button'
registration_form: 'form#registration'
groups_grid: '#groups-grid'
roles_grid: '#roles-grid'
groups_create_view: '#submit'
libraries:
selectors:
_: '#libraries_list'
create_new_library_btn: '#create-new-lib'
permission_library_btn: '.permission_library_btn'
toolbtn_save_permissions: '.toolbtn_save_permissions'
save_new_library_btn: '#save_new_library'
search_field: '#filterInput'
new_library_name_input: 'input[placeholder="Name"]'
new_library_description_input: 'input[placeholder="Description"]'
add_items_permission: '.add_library_item_role_list'
add_items_permission_input_field: '.add_library_item_role_list input'
add_items_permission_field_text: '.add_library_item_role_list .multiselect__tag span'
add_items_permission_option: '.add_library_item_role_list ul'
folder:
selectors:
add_items_button: '.add-library-items-datasets'
add_items_menu: '.add-library-items-datasets .dropdown-menu'
add_items_options: '.add-library-items-datasets .dropdown-menu div a'
add_folder: '.add-library-items-folder'
add_to_history: '.add-to-history'
add_to_history_datasets: '.add-to-history-datasets'
add_to_history_collection: '.add-to-history-collection'
# TODO: Most of these aren't very good selectors but the same DOM elements
# are reused without adding specific classes, IDs, or roles to anything.
import_modal: '.modal'
import_datasets_ok_button: '.modal-footer .buttons #button-0'
import_datasets_cancel_button: '.modal-footer .buttons #button-1'
export_to_history_options: '#library-collection-type-select'
export_to_history_paired_option: 'option[value="${collection_option}"]'
export_to_history_collection_name: '.collection-name'
export_to_history_new_history: 'input[name=history_name]'
clear_filters: '.clear-filters-link'
import_progress_bar: '.progress-bar-import'
import_history_content: '.library_selected_history_content'
import_history_contents_items: '.library_selected_history_content tbody > tr'
import_from_path_textarea: '#import_paths'
select_all: '#select-all-checkboxes'
select_one: '.lib-folder-checkbox'
select_dataset: 'tr[aria-rowindex="${rowindex}"] .lib-folder-checkbox'
empty_folder_message: '.empty-folder-message'
btn_open_parent_folder:
type: xpath
selector: '//a[contains(text(), "${folder_name}")]'
edit_folder_btn: '.edit_folder_btn'
description_field: '.description-field > div'
description_field_shrinked: '.shrinked-description'
save_folder_btn: '.save_folder_btn'
input_folder_name: 'textarea[name="input_folder_name"]'
input_folder_description: '.input_folder_description'
download_button: '#download-btn'
delete_btn: '.toolbtn-bulk-delete'
toast_msg: '.toast-message'
toast_warning: '.toast-warning'
select_import_dir_item: 'li[full_path="${name}"] .jstree-anchor'
import_dir_btn:
type: xpath
selector: '//button[contains(text(), "Import")]'
manage_dataset_permissions_btn: 'a[title="Permissions of ${name}"]'
make_private_btn: '#make-private'
access_dataset_roles: '.access_dataset_roles .multiselect__tag span'
private_dataset_icon: '.fa-key'
open_location_details_btn: '.details-btn'
location_details_ok_btn: '#details-modal .btn-primary'
labels:
from_history: 'from History'
from_path: 'from Path'
from_import_dir: 'from Import Directory'
from_user_import_dir: 'from User Directory'
dataset:
selectors:
table: '.dataset_table'
table_rows: '.dataset_table tbody tr'
grids:
selectors:
body: '#grid-table-body'
free_text_search: '#input-free-text-search-filter'
gies:
jupyter:
selectors:
body: 'body.notebook_app'
trusted_notification: '#notification_trusted'
selectors:
spinner: 'img#spinner'
iframe: 'body iframe[seamless="seamless"]'
upload:
selectors:
tab: '#tab-title-link-${tab}'
ftp_add: '#btn-ftp'
ftp_popup: '.upload-ftp-body'
ftp_items: '.upload-ftp-row'
ftp_close: '.popover-header .popover-close'
row: '#upload-row-${n}'
settings_button: '#upload-row-${n} .upload-settings'
settings: '.upload-settings-table'
setting_deferred: '.upload-deferred'
start: '.upload-button'
rule_source_content: 'textarea.upload-rule-source-content'
rule_select_data_type: '.rule-data-type'
rule_select_input_type: '.rule-select-type'
rule_dataset_selector:
selector: '.selection-dialog-modal'
rule_dataset_selector_row:
selector: '.selection-dialog-modal [aria-rowindex="${rowindex}"]'
build_btn: '#rule-based #btn-build'
file_source_selector:
type: xpath
selector: '//span[contains(@title, "${path}")]'
file_dialog_ok: '.file-dialog-modal-ok'
rule_builder:
selectors:
_: '.rule-collection-creator'
menu_button_filter: '.rule-menu-filter-button'
menu_button_rules: '.rule-menu-rules-button'
menu_button_column: '.rule-menu-column-button'
menu_item_rule_type: '.rule-link-${rule_type}'
rule_editor: '.rule-edit-${rule_type}'
rule_editor_ok: '.rule-editor-ok'
add_mapping_menu: '.rule-add-mapping'
add_mapping_button: '.rule-add-mapping-${mapping_type}'
mapping_edit: '.rule-map-${mapping_type} .select2-container'
mapping_remove_column: '.rule-map-${mapping_type} .rule-column-selector-target-remove'
mapping_add_column: '.rule-map-${mapping_type} .rule-column-selector-target-add'
mapping_ok: '.rule-mapping-ok'
main_button_ok: '.rule-btn-okay'
collection_name_input: 'input.collection-name'
view_source: '.rule-builder-view-source'
source: '.rule-source'
table: '#hot-table .htCore'
extension_select: '.rule-footer-extension-group .extension-select'
charts:
selectors:
visualize_button: '.ui-portlet .button i.fa-line-chart' # without icon - it waits on other buttons that aren't visible, need more specific class
viewport_canvas: 'svg.charts-viewport-canvas'
-917
View File
@@ -1,917 +0,0 @@
# top_level: {global: <components>, workflows: <components>, histories: <components>}
# components := {<subcomponent_name>: <components>} | <component>
# component := {selectors: <selectors_map>, labels: <labels_map>, ids: <id_map>}
# selectors_map := {<selector_name>: <selector>}
# selector := <str> | {type: <selector_type>, selector: <str>}
# selector_type := css|xpath|sizzle|id
# labels_map := {<label_name>: <label>}
_: # global stuff
selectors:
editable_text: '.editable-text'
tooltip_balloon: '.tooltip'
left_panel_drag: '#left > .unified-panel-footer > .drag'
left_panel_collapse: '#left > .unified-panel-footer > .panel-collapse'
right_panel_drag: '#right > .unified-panel-footer > .drag'
right_panel_collapse: '#right > .unified-panel-footer > .panel-collapse'
by_attribute: '${scope} [${name}="${value}"]'
messages:
selectors:
all: '[class*="alert"]'
error: '.alert-danger'
warning: '.alert-warning'
done: '.alert-success'
info: '.alert-info'
donelarge: '.donemessagelarge'
infolarge: '.infomessagelarge'
require_login: 'a.require-login-link'
masthead:
selectors:
_: '#masthead'
# bootstrap-vue a tag doesn't work as link target, need to hit span inside
user: '#user.loggedin-only > a.nav-link.dropdown-toggle > span'
register_or_login: '#user.loggedout-only > .nav-link'
user_menu: '#user .dropdown-menu a'
workflow: '#workflow .nav-link'
username:
type: xpath
selector: '//a[contains(text(), "Logged in as")]'
logged_in_only: '.loggedin-only'
logged_out_only: '.loggedout-only'
labels:
# top-level menus
analyze: 'Analyze Data'
workflow: 'Workflow'
shared_data: 'Shared Data'
visualization: 'Visualization'
help: 'Help'
user: 'User'
admin: 'Admin'
# user menu
logout: 'Logout'
custom_builds: 'Custom Builds'
preferences: 'Preferences'
histories: 'Histories'
invocations: 'Workflow Invocations'
pages: 'Pages'
# Shared data
libraries: 'Data Libraries'
published_histories: 'Histories'
preferences:
selectors:
sign_out: "#edit-preferences-sign-out"
change_password: "#edit-preferences-password"
manage_information: '#edit-preferences-information'
toolbox_filters: '#edit-preferences-toolbox-filters'
manage_api_key: '#edit-preferences-api-key'
current_email: "#user-preferences-current-email"
get_new_key: '#submit'
delete_account: '#delete-account'
delete_account_input: '#name-input'
delete_account_ok_btn: '.modal-footer .btn-primary'
toolbox_filters:
selectors:
input:
type: xpath
selector: "//span[contains(., '${description}')]/../div/div/label[@class='custom-control-label']"
submit: '#submit'
change_user_email:
selectors:
submit: '#submit'
change_user_password:
selectors:
submit: '#submit'
change_user_address:
selectors:
address_button:
type: xpath
selector: '//span[contains(text(), "Insert Address")]'
sign_out:
selectors:
cancel_button: '.modal-footer .buttons #button-0'
sign_out_button: '.modal-footer .buttons #button-1'
dataset_details:
selectors:
_: 'table#dataset-details'
tool_parameters: 'table#tool-parameters'
transform_action: '[data-transform-action="${action}"]'
deferred_source_uri: '.deferred-dataset-source-uri'
history_panel:
menu:
labels:
new: 'Create New'
item:
selectors:
# These now appear other places :_( - e.g. in the invocation view so we'll try
# prefixing ids with #current-history-panel but obviously we need to switch to classes or data
_: '#current-history-panel #${history_content_type}-${id}'
title: '${_} .content-title'
hid: '${_} .hid'
name: '${_} .name'
details: '${_} .details'
title_button_area: '${_} .primary-actions'
primary_action_buttons: '${_} .actions .left'
secondary_action_buttons: '${_} .actions .right'
summary: '${_} .summary'
blurb: '${_} .blurb .value'
dbkey: '${_} .dbkey .value'
info: '${_} .info .value'
peek: '${_} .dataset-peek'
toolhelp_title: '${_} .toolhelp strong'
# Title buttons...
display_button: '${_} .display-btn'
edit_button: '${_} .edit-btn'
delete_button: '${_} .delete-btn'
# Action buttons...
download_button: '${_} .icon-btn.download-btn'
info_button: '${_} .icon-btn.params-btn'
tool_help_button: '${_} .fa.fa-question'
rerun_button: '${_} .icon-btn.rerun-btn'
alltags: '${_} .alltags .ti-tags'
# beta content item
content_item:
selectors:
# specific rows selectable with attributes via suffix
_: '.history-index .content-item${suffix}'
title: '${_} .content-title'
details: '${_} .details'
summary: '${_} .summary'
hid: '${_} .hid'
name: '${_} .name'
blurb: '${_} .blurb .value'
dbkey: '${_} .dbkey .value'
info: '${_} .info .value'
peek: '${_} .dataset-peek'
toolhelp_title: '${_} .toolhelp strong'
# Title buttons...
display_button: '${_} .display-btn'
edit_button: '${_} .edit-btn'
delete_button: '${_} .delete-btn'
rerun_button: '${_} .rerun-btn'
# Action buttons...
download_button: '${_} .download-btn'
info_button: '${_} .params-btn'
alltags: '${_} .alltags .ti-tags'
dataset_operations_dropdown: '${_} .dataset-actions'
# re-usable history editor, scoped for use in different layout scenarios (multi, etc.)
editor:
selectors:
_: '${scope} [data-description="edit details"]'
name: '${_} [data-description="name display"]'
toggle: '${_} [data-description="editor toggle"]'
form: '${_} [data-description="edit form"]'
name_input: '${_} [data-description="name input"]'
annotation_input: '${_} [data-description="annotation input"]'
tags_input: '${_} .tags input'
save_button: '${_} [data-description="editor save button"]'
# beta history tags
tag_editor:
selectors:
_: '${scope} .details .tags'
toggle: '${_} .toggle-link'
display: '${_} .tag-area .tag-name'
input: '${_} input'
tag_area: '${_} .tag-area'
tag_close_btn: '${_} .ti-icon-close'
multi_operations:
selectors:
show_button: '.show-history-content-selectors-btn'
action_button: '.history-contents-list-action-menu-btn'
action_menu: '.list-action-menu .dropdown-menu'
labels:
build_pair: "Build Dataset Pair"
build_list: "Build Dataset List"
build_list_pairs: "Build List of Dataset Pairs"
build_from_rules: "Build Collection from Rules"
collection_view:
selectors:
_: '.dataset-collection-panel'
nav_menu: '[data-description="collection breadcrumbs menu"]'
back_button: '[data-description="collection breadcrumbs menu"] :last'
back: '.navigation .back'
title: '.dataset-collection-panel .controls .title .editable-text'
title_input: '.dataset-collection-panel .controls .title input'
subtitle: '.dataset-collection-panel .controls .title .subtitle'
elements_warning: '.dataset-collection-panel .controls .elements-warning'
tag_area_input: '.controls .tags-display .tags-input input'
list_items: '.dataset-collection-panel .list-items .list-item'
list_items_beta: '.dataset-collection-panel .listing .content-item'
selectors:
beta: '.history-index'
legacy: '.list-panel'
_: '#current-history-panel'
search: '#current-history-panel input.search-query'
refresh_button: '.history-refresh-button'
name: '.title .name'
name_beta: '.history-title span:last-child'
name_edit_input:
selector: 'name input'
type: data-description
contents: '#current-history-panel .history-content'
contents_beta: '.history-index .content-item'
empty_message: '.empty-message'
size: '.history-size'
tag_icon: '.actions .history-tag-btn'
tag_area: '.details .tags-display'
tag_area_input: '.details .tags-display .tags-input input'
tag_close_btn: '.tags-display .ti-icon-close'
tags: 'li.ti-tag.ti-valid .tag-name'
annotation_icon: '.actions .history-annotate-btn'
annotation_area: '.details .history-annotation'
annotation_editable_text:
selector: 'annotation value'
type: data-description
annotation_edit:
selector: 'annotation input'
type: data-description
annotation_done: '.details .history-annotation .annotation button'
options_button: '[data-description="history options"]'
options_button_icon: '.details .menu-expand-button'
options_button_icon_beta: '[data-description="history options"] button'
options_button_copy_datasets_beta: '.copy-datasets-menu-item'
options_menu: '.history-options-button-menu'
options_menu_item:
type: sizzle
selector: '.history-options-button-menu > a:contains("${option_label}")'
options_show_history_structure:
type: xpath
selector: '//a[contains(text(), "Show Structure")]'
options_show_export_history_to_file: 'a[data-description="export to file"]'
options_use_beta_history:
type: xpath
selector: '//a[text()="Use Beta History Panel"]'
options_use_legacy_history: 'a[data-description="switch to legacy history view"]'
collection_menu_button: '.collection-menu'
collection_menu_edit_attributes:
type: xpath
selector: '//button[@title="Edit attributes"]'
new_history_button: '.history-new-button'
multi_view_button: '.history-view-multi-button'
histories_operation_menu: '[data-description="history options"]'
multi_view_button_beta: '[data-description="switch to multi history view"]'
pagination_pages: '.list-pagination .pages'
pagination_pages_options: '.list-pagination .pages option'
pagination_pages_selected_option: '.list-pagination .pages option:checked'
pagination_next: '.list-pagination button.next'
pagination_previous: '.list-pagination button.prev'
text:
tooltip_name: 'Rename history...'
new_name: 'Unnamed history'
history_structure:
selectors:
_: '.tool'
header: '.tool > .header.clickable'
dataset: '.tool div.list-item.dataset.history-content'
details: '.tool .details'
edit_dataset_attributes:
selectors:
database_build_dropdown: '[data-label="Database/Build"]'
save_btn: '#dataset-attributes-default-save'
dbkey_dropdown_results:
selectors:
_: '#select2-drop > .select2-results'
dbkey_dropdown_option:
type: xpath
selector: '//li[normalize-space() = "${dbkey_text}"]'
edit_collection_attributes:
selectors:
database_genome_tab:
type: xpath
selector: '//a[contains(text(), "Database/Build")]'
database_value:
type: xpath
selector: '//span[contains(text(), "${dbkey}")]'
save_btn: '.save-collection-edit'
tool_panel:
selectors:
tool_link: 'a[href$$="tool_runner?tool_id=${tool_id}"]'
outer_tool_link: '.toolTitle a[href$$="tool_runner?tool_id=${tool_id}"]'
search: '.search-query'
workflow_names: '#internal-workflows .toolTitle'
views_button: '.tool-panel-dropdown'
views_menu_item: '[data-panel-id="${panel_id}"]'
panel_labels: '.tool-panel-label'
multi_history_view:
selectors:
_: '.multi-panel-history'
item: '.multi-panel-history #${history_content_type}-${id}'
histories: '.middle .history-column'
current_label: '.current-label'
create_new_button: '.create-new'
drag_drop_help: '.history-drop-target-help'
switch_history: '.switch-to'
history_dropdown_btn: '[history-dropdown-btn="${history_id}"]'
copy: '.copy-history'
delete: '.copy-history'
current_history_check: '#history-column-${history_id} .current-label'
empty_message_check: '.empty-message'
switch_button: '#history-column-${history_id} .switch-to'
history_dropdown_menu:
selectors:
_: '[history-dropdown-menu="${history_id}"]'
delete: '[history-dropdown-menu="${history_id}"] > .delete-history'
purge: '[history-dropdown-menu="${history_id}"] > .purge-history'
copy_history_modal:
selectors:
_: '.modal-dialog'
copy_btn:
type: xpath
selector: '//button[contains(text(), "Copy")]'
history_copy_elements:
selectors:
# Following two don't really work as CSS would only work as jQuery/sizzle I think
# since the page is dynamically generated.
# https://stackoverflow.com/questions/10645552/is-it-possible-to-use-an-input-value-attribute-as-a-css-selector
dataset_checkbox: "input[id='dataset|${id}']"
collection_checkbox: 'input[id="dataset_collection|${id}"]'
new_history_name: '#new_history_name'
copy_button: "input[type='submit']"
done_link: '.donemessage a'
collection_builders:
selectors:
clear_filters: "a.clear-filters-link"
forward_datasets: ".forward-column .column-datasets"
reverse_datasets: ".reverse-column .column-datasets"
histories:
labels:
import_button: 'Import history'
sharing:
selectors:
unshare_user_button: '.share_with_view .multiselect__tag-icon'
unshare_with_user_button: '.share_with_view [data-email="${email}"] .multiselect__tag-icon'
user_email_input: '.user-email-input-form'
submit_sharing_with: '.submit-sharing-with'
share_with_collapse: '.share-with-collapse'
share_with_multiselect: '.share_with_view > .multiselect'
share_with_input: '.share_with_view input'
make_accessible: '.make-accessible label'
make_publishable: '.make-publishable label'
labels:
unshare: 'Unshare'
files_dialog:
selectors:
ftp_label: 'a[title="label-gxftp://"]'
ftp_details: 'span[title="details-gxftp://"]'
row: 'span[title="label-${uri}"]'
back_btn: '#back-btn'
history_export:
selectors:
export_link: '.export-link'
running: '.history-export-component .loading-icon'
generated_export_link: '.generated-export-link'
copy_export_link: '.copy-export-link'
show_job_link: '.show-job-link'
job_table: '.info_data_table'
job_table_ok: '.job-information-modal .btn-primary'
tab_export_to_file: '.tab-export-to-file'
directory_input: '.directory-form-input'
name_input: '.export-to-remote-file #name'
export_button: '.export-button'
success_message: '.history-export-component .alert-success'
history_import:
selectors:
radio_button_remote_files: '.history-import-component .fa-folder-open'
import_button: '.import-button'
running: '.history-import-component .loading-icon'
success_message: '.history-import-component .alert-success'
pages:
selectors:
create: '.manage-table-actions .action-button'
submit: '#submit'
export: '.markdown-pdf-export'
editor:
selectors:
wym_iframe: 'div.wym_iframe iframe'
wym_iframe_content: '.text-content'
save: '#save-button'
embed_button: '#embed-galaxy-object'
dataset_selector: '.saved-datasets'
embed_dialog_add_button: '.pages-embed .buttons #button-0'
markdown_editor: '.markdown-textarea'
labels:
embed_dataset: 'Embed Dataset'
login:
selectors:
form: 'form#login'
submit:
type: xpath
selector: "//button[@name='login']"
registration:
selectors:
toggle: '#register-toggle'
form: 'form#registration'
submit:
type: xpath
selector: "//button[@name='create']"
tool_form:
selectors:
options: '.tool-dropdown'
execute: 'button#execute'
parameter_div: 'div.ui-form-element[id="form-element-${parameter}"]'
parameter_checkbox: 'div.ui-form-element[id="form-element-${parameter}"] .ui-switch div'
parameter_input: 'div.ui-form-element[id="form-element-${parameter}"] .ui-input'
parameter_textarea: 'div.ui-form-element[id="form-element-${parameter}"] textarea'
reference: '.formatted-reference'
about: '.tool-footer'
labels:
generate_tour: 'Generate Tour'
workflows:
selectors:
new_button: '#workflow-create'
import_button: '#workflow-import'
save_button: '#workflow-save-button'
search_box: "#workflow-search"
workflow_table: "#workflow-table"
workflow_rows: "#workflow-table > tbody > tr:not(.b-table-empty-row, [style*='display: none'])"
external_link: '.workflow-external-link'
trs_icon: '.workflow-trs-icon'
pager: '.gx-workflows-grid-pager'
pager_page: '.gx-workflows-grid-pager .gx-grid-pager-page [aria-posinset=${page}]'
pager_page_next: '.gx-workflows-grid-pager .gx-grid-pager-next button'
pager_page_first: '.gx-workflows-grid-pager .gx-grid-pager-first button'
pager_page_last: '.gx-workflows-grid-pager .gx-grid-pager-last button'
pager_page_previous: '.gx-workflows-grid-pager .gx-grid-pager-prev button'
pager_page_active: '.gx-workflows-grid-pager .gx-grid-pager-page.active button'
trs_search:
selectors:
search: "#trs-search-query"
search_result:
type: xpath
selector: "//td[contains(text(), '${workflow_name}')]"
import_button: ".workflow-import"
select_server_button: "#dropdownTrsServer"
import_version: '[data-version-name*="${version}"]'
select_server:
type: xpath
selector: "//a[contains(@class, 'dropdown-item') and text() = '${server}']"
trs_import:
selectors:
input: "#trs-id-input"
# *= means attribute value contains "${version}"
# needed because dockstore uses branch or git tag, while workflowhub
# concatenates name and version
import_version: '[data-version-name*="${version}"]'
select_server_button: "#dropdownTrsServer"
select_server:
type: xpath
selector: "//a[contains(@class, 'dropdown-item') and text() = '${server}']"
workflow_run:
selectors:
warning: ".ui-form-composite .alert-warning"
input_div: "[step-label='${label}']"
input_data_div: "[step-label='${label}'] .select2-container"
# TODO: put step labels in the DOM ideally
subworkflow_step_icon: ".portlet-title-icon.fa-sitemap"
run_workflow: "#run-workflow"
validation_error: ".validation-error"
expand_form_link: '.workflow-expand-form-link'
expanded_form: '.workflow-expanded-form'
new_history_target_link: '.workflow-new-history-target-link'
runtime_setting_button: '.workflow-run-settings'
runtime_setting_target: '.workflow-run-settings-target'
input_select_field:
type: xpath
selector: '//div[@data-label="${label}"]//span[@class="select2-chosen"]'
workflow_editor:
node:
selectors:
_: "[node-label='${label}']"
title: '${_} .node-title'
destroy: '${_} .node-destroy'
clone: '${_} .node-clone'
output_terminal: "${_} [output-name='${name}']"
input_terminal: "${_} [input-name='${name}']"
input_mapping_icon: "${_} [input-name='${name}'].multiple"
selectors:
canvas_body: '#workflow-canvas'
edit_annotation: '#workflow-annotation'
edit_name: '#workflow-name'
tool_menu: '.toolMenuContainer'
tool_menu_section_link: '.tool-menu-section-${section_name} a span'
tool_menu_item_link: 'a.tool-menu-item-${item_name}'
workflow_link:
type: xpath
selector: '//a[contains(., "${workflow_title}")]'
connect_icon: 'div.ui-form-element[id="form-element-${name}"] .ui-form-connected-icon'
collapse_icon: 'div.ui-form-element[id="form-element-${name}"] .ui-form-collapsible-icon'
node_title:
type: xpath
selector: '//span[@class="node-title" and text()="${title}"]'
label_input:
type: xpath
selector: >
//div[@id='form-element-__label' and not(ancestor::div[contains(@style,'display: none')])]//input
annotation_input:
type: xpath
selector: >
//div[@id='form-element-__annotation' and not(ancestor::div[contains(@style,'display: none')])]//textarea
configure_output:
type: xpath
selector: >
//b[text()="Configure Output: '${output}'"]
label_output:
type: xpath
selector: >
//div[@id='form-element-__label__${output}' and not(ancestor::div[contains(@style,'display: none')])]//input
rename_output:
type: xpath
selector: >
//div[@data-label='Rename dataset']//input
change_datatype:
type: xpath
selector: >
//div[@data-label='Change datatype' and not(ancestor::div[contains(@style,'display: none')])]//span[contains(@class, 'select2-chosen')]
select_dataype_text_search:
type: xpath
selector: >
//div[@class="select2-search" and not(ancestor::div[contains(@style,'display: none')])]//input
select_datatype:
type: xpath
selector: >
//div[@class="select2-result-label" and contains(text(), "${datatype}") and not(ancestor::div[contains(@style,'display: none')])]
add_tags:
type: xpath
selector: >
//div[@data-label='Add Tags' and not(ancestor::div[contains(@style,'display: none')])]//input
remove_tags:
type: xpath
selector: >
//div[@data-label='Remove Tags' and not(ancestor::div[contains(@style,'display: none')])]//input
tool_version_button: ".tool-versions"
connector_for: "div[output-handle-id='${source_id}'][input-handle-id='${sink_id}']"
connector_destroy_callout: '.delete-terminal'
save_button: '.editor-button-save'
state_modal_body: '.state-upgrade-modal'
modal_button_continue: '.modal-footer .btn'
workflow_show:
selectors:
title: 'h3.item_name'
annotation: '.page-item-header .annotation'
invocations:
selectors:
invocations_table: '.invocations-list table'
invocations_table_rows: '.invocations-list table tbody tr:not(.b-table-empty-row, [style*="display: none"])'
pager: '.gx-invocations-grid-pager'
pager_page: '.gx-invocations-grid-pager .gx-grid-pager-page [aria-posinset=${page}]'
pager_page_next: '.gx-invocations-grid-pager .gx-grid-pager-next button'
pager_page_last: '.gx-invocations-grid-pager .gx-grid-pager-last button'
pager_page_first: '.gx-invocations-grid-pager .gx-grid-pager-first button'
pager_page_previous: '.gx-invocations-grid-pager .gx-grid-pager-prev button'
pager_page_active: '.gx-invocations-grid-pager .gx-grid-pager-page.active button'
state_details: '.workflow-invocation-state-component'
toggle_invocation_details: '.toggle-invocation-details'
progress_steps_note: '.workflow-invocation-state-component .steps-progress .progressNote'
progress_jobs_note: '.workflow-invocation-state-component .jobs-progress .progressNote'
input_details: '.workflow-invocation-state-component .invocation-inputs-details'
input_details_title: '.workflow-invocation-state-component .invocation-inputs-details [data-label="${label}"]'
input_details_name: '.workflow-invocation-state-component .invocation-inputs-details [data-label="${label}"] .name'
steps_details: '.workflow-invocation-state-component .invocation-steps-details'
step_title: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .step-title'
step_details: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .portlet-operations'
step_output_collection: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-output-collection-details'
step_output_collection_toggle: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-output-collection-details .name'
step_output_collection_element_identifier:
type: xpath
selector: '//span[@class="content-title name"][text()="${element_identifier}"]'
step_output_collection_element_datatype: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-output-collection-details .datatype .value'
step_job_details: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details'
step_job_table: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table'
step_job_table_rows: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table tbody tr'
step_job_information: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table tbody .b-table-details .info_data_table'
step_job_information_tool_id: '.workflow-invocation-state-component .invocation-steps-details [data-step="${order_index}"] .invocation-step-job-details table tbody .b-table-details .info_data_table #galaxy-tool-id'
tour:
popover:
selectors:
_: '.tour-element'
title: '${_} .tour-title'
content: '${_} .tour-content'
next: '${_} .tour-next'
end: '${_} .tour-end'
admin:
allowlist:
selectors:
toolshed:
type: xpath
selector: '//a[contains(text(), "Toolshed Tools")]'
local:
type: xpath
selector: '//a[contains(text(), "Local Tools")]'
sanitized:
type: xpath
selector: '//a[contains(text(), "HTML Sanitized")]'
rendered_active:
type: xpath
selector: '//div[contains(@class, "active")]//a[contains(text(), "HTML Rendered")]'
manage_dependencies:
selectors:
dependencies: 'a[contains(text(), "Dependencies")]'
containers: 'a[contains(text(), "Containers")]'
unused: 'a[contains(text(), "Unused")]'
resolver_type: '#manage-resolver-type'
container_type: '#manage-container-type'
unused_paths: '#unused-paths-table'
manage_jobs:
selectors:
job_lock: '#prevent-job-dispatching'
job_lock_label:
type: xpath
selector: "//label[@for='prevent-job-dispatching']/strong"
cutoff: '#cutoff'
toolshed:
selectors:
repo_search: '#toolshed-repo-search'
search_results: '#shed-search-results'
upgrade_notification: '#repository-table .badge'
index:
selectors:
datatypes: '#admin-link-datatypes'
dependencies: '#admin-link-manage-dependencies'
data_tables: '#admin-link-data-tables'
display_applications: '#admin-link-display-applications'
errors: '#admin-link-error-stack'
forms: '#admin-link-forms'
jobs: '#admin-link-jobs'
local_data: '#admin-link-local-data'
metadata: '#admin-link-metadata'
tool_versions: '#admin-link-tool-versions'
toolshed: '#admin-link-toolshed'
users: '#admin-link-users'
quotas: '#admin-link-quotas'
groups: '#admin-link-groups'
roles: '#admin-link-roles'
impersonate: '#admin-link-impersonate'
allowlist: '#admin-link-allowlist'
selectors:
warning: '#center .alert-warning'
# TODO: place betters IDS or something on this in these grids in the DOM
jobs_title: '#jobs-title'
datatypes_grid: '#data-types-grid'
data_tables_grid: '#data-tables-grid'
display_applications_grid: '#display-applications-grid'
update_jobs: 'form[name="jobs"]'
dm_title: '#data-managers-title'
dm_data_managers_card: '#data-managers-card'
dm_jobs_button: '#${data_manager}-jobs'
dm_jobs_breadcrumb: '#breadcrumb'
dm_jobs_table: '#jobs-table'
dm_job: '#job-${job_id}'
dm_job_breadcrumb: '#breadcrumb'
dm_job_data_manager_card: '#data-manager-card'
dm_job_data_card: '#data-card-${hda_index}'
dm_table_button: '#${data_table}-table'
dm_table_card: '#data-table-card'
users_grid: '#users-grid'
users_grid_create_button: '.manage-table-actions .action-button'
groups_grid_create_button: '.manage-table-actions .action-button'
registration_form: 'form#registration'
groups_grid: '#groups-grid'
roles_grid: '#roles-grid'
groups_create_view: '#submit'
libraries:
selectors:
_: '#libraries_list'
create_new_library_btn: '#create-new-lib'
permission_library_btn: '.permission_library_btn'
toolbtn_save_permissions: '.toolbtn_save_permissions'
save_new_library_btn: '#save_new_library'
search_field: '#filterInput'
new_library_name_input: 'input[placeholder="Name"]'
new_library_description_input: 'input[placeholder="Description"]'
add_items_permission: '.add_library_item_role_list'
add_items_permission_input_field: '.add_library_item_role_list input'
add_items_permission_field_text: '.add_library_item_role_list .multiselect__tag span'
add_items_permission_option: '.add_library_item_role_list ul'
folder:
selectors:
add_items_button: '.add-library-items-datasets'
add_items_menu: '.add-library-items-datasets .dropdown-menu'
add_items_options: '.add-library-items-datasets .dropdown-menu div a'
add_folder: '.add-library-items-folder'
add_to_history: '.add-to-history'
add_to_history_datasets: '.add-to-history-datasets'
add_to_history_collection: '.add-to-history-collection'
# TODO: Most of these aren't very good selectors but the same DOM elements
# are reused without adding specific classes, IDs, or roles to anything.
import_modal: '.modal'
import_datasets_ok_button: '.modal-footer .buttons #button-0'
import_datasets_cancel_button: '.modal-footer .buttons #button-1'
export_to_history_options: '#library-collection-type-select'
export_to_history_paired_option: 'option[value="${collection_option}"]'
export_to_history_collection_name: '.collection-name'
export_to_history_new_history: 'input[name=history_name]'
clear_filters: '.clear-filters-link'
import_progress_bar: '.progress-bar-import'
import_history_content: '.library_selected_history_content'
import_history_contents_items: '.library_selected_history_content tbody > tr'
import_from_path_textarea: '#import_paths'
select_all: '#select-all-checkboxes'
select_one: '.lib-folder-checkbox'
select_dataset: 'tr[aria-rowindex="${rowindex}"] .lib-folder-checkbox'
empty_folder_message: '.empty-folder-message'
btn_open_parent_folder:
type: xpath
selector: '//a[contains(text(), "${folder_name}")]'
edit_folder_btn: '.edit_folder_btn'
description_field: '.description-field > div'
description_field_shrinked: '.shrinked-description'
save_folder_btn: '.save_folder_btn'
input_folder_name: 'textarea[name="input_folder_name"]'
input_folder_description: '.input_folder_description'
download_button: '#download-btn'
delete_btn: '.toolbtn-bulk-delete'
toast_msg: '.toast-message'
toast_warning: '.toast-warning'
select_import_dir_item: 'li[full_path="${name}"] .jstree-anchor'
import_dir_btn:
type: xpath
selector: '//button[contains(text(), "Import")]'
manage_dataset_permissions_btn: 'a[title="Permissions of ${name}"]'
make_private_btn: '#make-private'
access_dataset_roles: '.access_dataset_roles .multiselect__tag span'
private_dataset_icon: '.fa-key'
open_location_details_btn: '.details-btn'
location_details_ok_btn: '#details-modal .btn-primary'
labels:
from_history: 'from History'
from_path: 'from Path'
from_import_dir: 'from Import Directory'
from_user_import_dir: 'from User Directory'
dataset:
selectors:
table: '.dataset_table'
table_rows: '.dataset_table tbody tr'
grids:
selectors:
body: '#grid-table-body'
free_text_search: '#input-free-text-search-filter'
gies:
jupyter:
selectors:
body: 'body.notebook_app'
trusted_notification: '#notification_trusted'
selectors:
spinner: 'img#spinner'
iframe: 'body iframe[seamless="seamless"]'
upload:
selectors:
tab: '#tab-title-link-${tab}'
ftp_add: '#btn-ftp'
ftp_popup: '.upload-ftp-body'
ftp_items: '.upload-ftp-row'
ftp_close: '.popover-header .popover-close'
row: '#upload-row-${n}'
settings_button: '#upload-row-${n} .upload-settings'
settings: '.upload-settings-table'
setting_deferred: '.upload-deferred'
start: '.upload-button'
rule_source_content: 'textarea.upload-rule-source-content'
rule_select_data_type: '.rule-data-type'
rule_select_input_type: '.rule-select-type'
rule_dataset_selector:
selector: '.selection-dialog-modal'
rule_dataset_selector_row:
selector: '.selection-dialog-modal [aria-rowindex="${rowindex}"]'
build_btn: '#rule-based #btn-build'
file_source_selector:
type: xpath
selector: '//span[contains(@title, "${path}")]'
file_dialog_ok: '.file-dialog-modal-ok'
rule_builder:
selectors:
_: '.rule-collection-creator'
menu_button_filter: '.rule-menu-filter-button'
menu_button_rules: '.rule-menu-rules-button'
menu_button_column: '.rule-menu-column-button'
menu_item_rule_type: '.rule-link-${rule_type}'
rule_editor: '.rule-edit-${rule_type}'
rule_editor_ok: '.rule-editor-ok'
add_mapping_menu: '.rule-add-mapping'
add_mapping_button: '.rule-add-mapping-${mapping_type}'
mapping_edit: '.rule-map-${mapping_type} .select2-container'
mapping_remove_column: '.rule-map-${mapping_type} .rule-column-selector-target-remove'
mapping_add_column: '.rule-map-${mapping_type} .rule-column-selector-target-add'
mapping_ok: '.rule-mapping-ok'
main_button_ok: '.rule-btn-okay'
collection_name_input: 'input.collection-name'
view_source: '.rule-builder-view-source'
source: '.rule-source'
table: '#hot-table .htCore'
extension_select: '.rule-footer-extension-group .extension-select'
charts:
selectors:
visualize_button: '.ui-portlet .button i.fa-line-chart' # without icon - it waits on other buttons that aren't visible, need more specific class
viewport_canvas: 'svg.charts-viewport-canvas'
+1
View File
@@ -0,0 +1 @@
../../../client/src/utils/navigation/navigation.yml