Skip to content

Commit

Permalink
fix seleniums and add jest for compact FilterMenus
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedhamidawan committed Mar 21, 2024
1 parent 008b652 commit 9176b9a
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 40 deletions.
56 changes: 41 additions & 15 deletions client/src/components/Common/FilterMenu.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { createTestingPinia } from "@pinia/testing";
import { getLocalVue } from "@tests/jest/helpers";
import { mount, Wrapper } from "@vue/test-utils";

import { HistoryFilters } from "@/components/History/HistoryFilters";
import { WorkflowFilters } from "@/components/Workflow/WorkflowFilters";
import Filtering, { compare, contains, equals, toBool, toDate } from "@/utils/filtering";

import FilterMenu from "./FilterMenu.vue";
Expand Down Expand Up @@ -80,6 +82,7 @@ describe("FilterMenu", () => {
stubs: {
icon: { template: "<div></div>" },
},
pinia: createTestingPinia(),
});
}

Expand All @@ -89,11 +92,13 @@ describe("FilterMenu", () => {
await searchButton.trigger("click");
}

async function expectCorrectEmits(showAdvanced: boolean, filterText: string, filterClass: Filtering<unknown>) {
async function expectCorrectEmits(filterText: string, filterClass: Filtering<unknown>, showAdvanced?: boolean) {
if (showAdvanced !== undefined) {
const toggleEmit = (wrapper.emitted()?.["update:show-advanced"]?.length ?? 0) - 1;
expect(wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0]).toEqual(showAdvanced);
await wrapper.setProps({ showAdvanced: wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0] });
}
const filterEmit = (wrapper.emitted()["update:filter-text"]?.length ?? 0) - 1;
const toggleEmit = (wrapper.emitted()?.["update:show-advanced"]?.length ?? 0) - 1;
expect(wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0]).toEqual(showAdvanced);
await wrapper.setProps({ showAdvanced: wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0] });
const receivedText = wrapper.emitted()["update:filter-text"]?.[filterEmit]?.[0];
const receivedDict = filterClass.getQueryDict(receivedText);
const parsedDict = filterClass.getQueryDict(filterText);
Expand Down Expand Up @@ -185,11 +190,11 @@ describe("FilterMenu", () => {
// perform search
await performSearch();
await expectCorrectEmits(
false,
"create_time>'January 1, 2022' create_time<'January 1, 2023' " +
"filter_key:item-filter has_help:has-help-filter list_item:1234 " +
"number>1234 number<5678 name:name-filter radio:true bool_def:true",
TestFilters
TestFilters,
false,
);
});

Expand All @@ -209,17 +214,17 @@ describe("FilterMenu", () => {
// -------- Test keyup.enter key: ---------
// toggles view out and performs a search
await filterName.trigger("keyup.enter");
await expectCorrectEmits(false, "name:'sample name'", TestFilters);
await expectCorrectEmits("name:'sample name'", TestFilters, false);

// Test: clearing the filterText
const clearButton = wrapper.find("[data-description='reset query']");
await clearButton.trigger("click");
await expectCorrectEmits(false, "", TestFilters);
await expectCorrectEmits("", TestFilters, false);

// Test: toggling view back in
const toggleButton = wrapper.find("[data-description='toggle advanced search']");
await toggleButton.trigger("click");
await expectCorrectEmits(true, "", TestFilters);
await expectCorrectEmits("", TestFilters, true);

// -------- Test keyup.esc key: ---------
// toggles view out only (doesn't cause a new search / doesn't emulate enter)
Expand All @@ -232,7 +237,7 @@ describe("FilterMenu", () => {

// press esc key from name field (should not change emitted filterText unlike enter key)
await filterName.trigger("keyup.esc");
await expectCorrectEmits(false, "", TestFilters);
await expectCorrectEmits("", TestFilters, false);
});

/**
Expand Down Expand Up @@ -260,13 +265,13 @@ describe("FilterMenu", () => {

// expect "deleted = any" filter to be applied
await performSearch();
await expectCorrectEmits(false, "visible:true", HistoryFilters);
await expectCorrectEmits("visible:true", HistoryFilters, false);

// -------- Testing visible filter now: ---------

const toggleButton = wrapper.find("[data-description='toggle advanced search']");
await toggleButton.trigger("click");
await expectCorrectEmits(true, "visible:true", HistoryFilters);
await expectCorrectEmits("visible:true", HistoryFilters, true);
const visibleFilterBtnGrp = wrapper.find("[data-description='filter visible']");
const visibleFilterAnyBtn = visibleFilterBtnGrp.find(".btn-secondary");
expect(visibleFilterAnyBtn.text()).toBe("Any");
Expand All @@ -283,13 +288,34 @@ describe("FilterMenu", () => {

// expect "visible = any" filter to be applied
await performSearch();
await expectCorrectEmits(false, "deleted:any visible:any", HistoryFilters);
await expectCorrectEmits("deleted:any visible:any", HistoryFilters, false);

// -------- Testing repeated search if it prevents bug: ---------
// (bug reported here: https://github.com/galaxyproject/galaxy/issues/16211)
await toggleButton.trigger("click");
await expectCorrectEmits(true, "deleted:any visible:any", HistoryFilters);
await expectCorrectEmits("deleted:any visible:any", HistoryFilters, true);
await performSearch();
await expectCorrectEmits(false, "deleted:any visible:any", HistoryFilters);
await expectCorrectEmits("deleted:any visible:any", HistoryFilters, false);
});

/**
* Testing the default values of the filters defined in the HistoryFilters: Filtering
* class, ensuring the default values are reflected in the radio-group buttons
*/
it("test compact menu with checkbox filters on WorkflowFilters", async () => {
const myWorkflowFilters = WorkflowFilters("my");
setUpWrapper("Workflows", "search workflows", myWorkflowFilters);
// a compact `FilterMenu` only needs to be opened once (doesn't toggle out automatically)
await wrapper.setProps({ showAdvanced: true, view: "compact" });

// -------- Testing auto search on value change: ---------
const nameFilterInput = wrapper.find("#workflows-advanced-filter-name");
await nameFilterInput.setValue("myworkflow");
await expectCorrectEmits("name:myworkflow", myWorkflowFilters);

// -------- Testing deleted filter first: ---------
const deletedFilterCheckbox = wrapper.find("[data-description='filter deleted'] input");
await deletedFilterCheckbox.setChecked();
await expectCorrectEmits("name:myworkflow is:deleted", myWorkflowFilters);
});
});
4 changes: 3 additions & 1 deletion client/src/components/Common/FilterMenuBoolean.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ const value = computed({
<div :class="{ 'd-flex': isCheckbox }" @keyup.enter="emit('on-enter')" @keyup.esc="emit('on-esc')">
<small :class="{ 'mr-1': isCheckbox }">{{ props.filter.placeholder }}:</small>

<BFormCheckbox v-if="isCheckbox" v-model="value" :data-description="`filter ${props.name}`" />
<div v-if="isCheckbox" :data-description="`filter ${props.name}`">
<BFormCheckbox v-model="value" />
</div>
<BFormGroup v-else class="m-0">
<BFormRadioGroup
v-model="value"
Expand Down
4 changes: 0 additions & 4 deletions client/src/utils/navigation/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,6 @@ published_histories:
advanced_search_tag_area: '#histories-advanced-filter-tag .stateless-tags button'
advanced_search_tag_input: '#histories-advanced-filter-tag .stateless-tags input'
advanced_search_toggle: '#histories-published-grid [data-description="toggle advanced search"]'
advanced_search_submit: '#histories-advanced-filter-submit'
search_input: '#histories-published-grid input.search-query[data-description="filter text input"]'
tab: '#histories-published-tab'

Expand Down Expand Up @@ -435,8 +434,6 @@ histories:
selectors:
advanced_search_toggle: '#histories-grid [data-description="toggle advanced search"]'
advanced_search_name_input: '#histories-advanced-filter-name'
advanced_search_filter: '#histories-grid [data-description="filter ${filter}"] .btn'
advanced_search_submit: '#histories-advanced-filter-submit'
advanced_search_tag_area: '#histories-advanced-filter-tag .stateless-tags button'
advanced_search_tag_input: '#histories-advanced-filter-tag .stateless-tags input'
histories: '.grid-table tr'
Expand Down Expand Up @@ -588,7 +585,6 @@ workflows:
advanced_search_toggle: '.workflows-list [data-description="toggle advanced search"]'
advanced_search_name_input: '#workflows-advanced-filter-name'
advanced_search_tag_input: '#workflows-advanced-filter-tag .stateless-tags'
advanced_search_submit: '#workflows-advanced-filter-submit'
workflow_rows: "#workflow-table > tbody > tr:not(.b-table-empty-row, [style*='display: none'])"
workflows_list: '#workflows-list'
workflows_list_empty: '#workflow-list-empty'
Expand Down
1 change: 0 additions & 1 deletion client/src/utils/navigation/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ interface Rootpublished_histories extends Component {
advanced_search_toggle: SelectorTemplate;
advanced_search_name_input: SelectorTemplate;
advanced_search_tag_input: SelectorTemplate;
advanced_search_submit: SelectorTemplate;
tag_content: SelectorTemplate;
column_header: SelectorTemplate;
}
Expand Down
6 changes: 6 additions & 0 deletions lib/galaxy/selenium/navigates_galaxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,12 @@ def check_grid_rows(self, grid_name, item_names):
# bootstrap vue checkbox seems to be hidden by label, but the label is not interactable
self.driver.execute_script("$(arguments[0]).click();", checkbox)

def check_advanced_search_filter(self, filter_name):
filter_div = self.wait_for_selector(f"[data-description='filter {filter_name}']")
checkbox = filter_div.find_element(self.by.CSS_SELECTOR, "input")
# bootstrap vue checkbox seems to be hidden by label, but the label is not interactable
self.driver.execute_script("$(arguments[0]).click();", checkbox)

def published_grid_search_for(self, search_term=None):
return self._inline_search_for(
self.navigation.grids.free_text_search,
Expand Down
19 changes: 4 additions & 15 deletions lib/galaxy_test/selenium/test_histories_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ def test_history_publish(self):

self.navigate_to_histories_page()
self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_filter(filter="published").wait_for_and_click()
self.components.histories.advanced_search_submit.wait_for_and_click()
self.check_advanced_search_filter("published")
self.sleep_for(self.wait_types.UX_RENDER)

self.assert_histories_in_grid([self.history2_name])
Expand Down Expand Up @@ -85,8 +84,7 @@ def test_delete_and_undelete_history(self):
self.assert_histories_in_grid([self.history2_name], False)

self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_filter(filter="deleted").wait_for_and_click()
self.components.histories.advanced_search_submit.wait_for_and_click()
self.check_advanced_search_filter("deleted")
self.sleep_for(self.wait_types.UX_RENDER)

# Restore the history
Expand All @@ -113,8 +111,7 @@ def test_permanently_delete_history(self):
self.assert_histories_in_grid([self.history4_name], False)

self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_filter(filter="purged").wait_for_and_click()
self.components.histories.advanced_search_submit.wait_for_and_click()
self.check_advanced_search_filter("purged")
self.sleep_for(self.wait_types.UX_RENDER)

self.assert_histories_in_grid([self.history4_name])
Expand All @@ -137,8 +134,7 @@ def test_delete_and_undelete_multiple_histories(self):

# Display deleted histories
self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_filter(filter="deleted").wait_for_and_click()
self.components.histories.advanced_search_submit.wait_for_and_click()
self.check_advanced_search_filter("deleted")

# Select multiple histories
self.sleep_for(self.wait_types.UX_RENDER)
Expand Down Expand Up @@ -188,33 +184,26 @@ def test_advanced_search(self):
# search by name
self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_name_input.wait_for_and_send_keys(self.history3_name)
self.components.histories.advanced_search_submit.wait_for_and_click()
self.assert_histories_present([self.history3_name])

self.components.histories.reset_input.wait_for_and_click()

self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_name_input.wait_for_and_send_keys(self.history2_name)
self.components.histories.advanced_search_submit.wait_for_and_click()
self.assert_histories_present([self.history2_name])

self.components.histories.reset_input.wait_for_and_click()

self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_name_input.wait_for_and_send_keys(self.history4_name)
self.components.histories.advanced_search_submit.wait_for_and_click()
self.assert_histories_present([])

self.components.histories.reset_input.wait_for_and_click()

# search by tags
self.components.histories.advanced_search_toggle.wait_for_and_click()
self.components.histories.advanced_search_tag_area.wait_for_and_click()
input_element = self.components.histories.advanced_search_tag_input.wait_for_visible()
input_element.send_keys(self.history3_tags[0])
self.send_enter(input_element)
self.sleep_for(self.wait_types.UX_RENDER)
self.components.histories.advanced_search_submit.wait_for_and_click()
self.assert_histories_present([self.history3_name])

@retry_assertion_during_transitions
Expand Down
1 change: 0 additions & 1 deletion lib/galaxy_test/selenium/test_histories_published.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def test_published_histories_search_advanced(self):
self.send_escape(input_element)
self.sleep_for(self.wait_types.UX_RENDER)

self.components.published_histories.advanced_search_submit.wait_for_and_click()
self.assert_histories_present([self.history3_name])

@retry_assertion_during_transitions
Expand Down
3 changes: 0 additions & 3 deletions lib/galaxy_test/selenium/test_workflow_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ def test_index_advanced_search(self):
self.components.workflows.advanced_search_name_input.wait_for_and_send_keys("searchforthis")
self.components.workflows.advanced_search_tag_input.wait_for_and_click()
self.tagging_add(["mytag"])
self.components.workflows.advanced_search_submit.wait_for_and_click()
self._assert_showing_n_workflows(1)
curr_value = self.workflow_index_get_current_filter()
assert curr_value == "name:searchforthis tag:mytag", curr_value
Expand All @@ -193,11 +192,9 @@ def test_index_advanced_search(self):
curr_value = self.workflow_index_get_current_filter()
assert curr_value == "", curr_value

self.components.workflows.advanced_search_toggle.wait_for_and_click()
# search by 2 tags, one of which is not present
self.components.workflows.advanced_search_tag_input.wait_for_and_click()
self.tagging_add(["'mytag'", "'DNEtag'"])
self.components.workflows.advanced_search_submit.wait_for_and_click()
curr_value = self.workflow_index_get_current_filter()
assert curr_value == "tag:'mytag' tag:'DNEtag'", curr_value
self.components.workflows.workflow_not_found_message.wait_for_visible()
Expand Down

0 comments on commit 9176b9a

Please sign in to comment.