From 3adf2741e8a13bfbdb581d5d6f2f267cd76b96e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Wed, 23 Jul 2025 14:06:50 +0200 Subject: [PATCH] Adapt specs --- app/views/search/index.html.erb | 8 ++- .../global-search-work-packages.component.ts | 4 +- .../services/global-search.service.ts | 5 ++ .../spec/features/meetings_search_spec.rb | 7 ++- spec/features/search/search_spec.rb | 56 ++++++++++--------- spec/support/components/global_search.rb | 11 ++++ 6 files changed, 58 insertions(+), 33 deletions(-) diff --git a/app/views/search/index.html.erb b/app/views/search/index.html.erb index 427ddd78bd4..af144b0491b 100644 --- a/app/views/search/index.html.erb +++ b/app/views/search/index.html.erb @@ -56,17 +56,19 @@ See COPYRIGHT and LICENSE files for more details. ].compact ) - header.with_tab_nav(label: nil) do |tab_nav| + header.with_tab_nav(label: nil, test_selector: "search-tabs") do |tab_nav| search_types.each do |name| tab_nav.with_tab( + test_selector: "search-tab-#{name}", selected: search_params[:filter] == name, - href: search_path(filter: name, q: @question, scope: search_params[:scope]) + href: search_path(project_id: @project, filter: name, q: @question, scope: search_params[:scope]) ) { |t| t.with_text { OpenProject::GlobalSearch.tab_name(name) } } end tab_nav.with_tab( + test_selector: "search-tab-all", selected: search_params[:filter].blank?, - href: search_path(q: @question, scope: search_params[:scope]) + href: search_path(project_id: @project, q: @question, scope: search_params[:scope]) ) { |t| t.with_text { OpenProject::GlobalSearch.tab_name("all") } } end end diff --git a/frontend/src/app/core/global_search/global-search-work-packages.component.ts b/frontend/src/app/core/global_search/global-search-work-packages.component.ts index 6a6d03b0c9b..e827154c1cd 100644 --- a/frontend/src/app/core/global_search/global-search-work-packages.component.ts +++ b/frontend/src/app/core/global_search/global-search-work-packages.component.ts @@ -57,6 +57,7 @@ import { } from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive'; import { QueryRequestParams } from 'core-app/features/work-packages/components/wp-query/url-params-helper'; import { populateInputsFromDataset } from 'core-app/shared/components/dataset-inputs'; +import { CurrentProjectService } from 'core-app/core/current-project/current-project.service'; @Component({ selector: 'opce-global-search-work-packages', @@ -93,6 +94,7 @@ export class GlobalSearchWorkPackagesComponent extends UntilDestroyedMixin imple readonly halResourceService:HalResourceService, readonly wpTableFilters:WorkPackageViewFiltersService, readonly querySpace:IsolatedQuerySpace, + readonly currentProject:CurrentProjectService, readonly cdRef:ChangeDetectorRef, ) { super(); @@ -134,7 +136,7 @@ export class GlobalSearchWorkPackagesComponent extends UntilDestroyedMixin imple columns = ['id', 'subject', 'type', 'status', 'updatedAt']; } - if (this.scope === '') { + if (this.scope === '' && this.currentProject.id) { filters.push({ subprojectId: { operator: '*', diff --git a/frontend/src/app/core/global_search/services/global-search.service.ts b/frontend/src/app/core/global_search/services/global-search.service.ts index de9eb6250d4..38f17e17697 100644 --- a/frontend/src/app/core/global_search/services/global-search.service.ts +++ b/frontend/src/app/core/global_search/services/global-search.service.ts @@ -61,6 +61,11 @@ export class GlobalSearchService { params.set('q', query); params.set('scope', scope); + // Filter work packages by default + if (!params.get('filter')) { + params.set('filter', 'work_packages'); + } + return params.toString(); } } diff --git a/modules/meeting/spec/features/meetings_search_spec.rb b/modules/meeting/spec/features/meetings_search_spec.rb index 23d32e4f4eb..ed400c8df15 100644 --- a/modules/meeting/spec/features/meetings_search_spec.rb +++ b/modules/meeting/spec/features/meetings_search_spec.rb @@ -38,6 +38,7 @@ RSpec.describe "Meeting search", :js do let!(:meeting) { create(:meeting, project:) } let!(:agenda_item) { create(:meeting_agenda_item, meeting:) } + let(:global_search) { Components::GlobalSearch.new } before do login_as user @@ -52,7 +53,7 @@ RSpec.describe "Meeting search", :js do select_text: "In this project ↵", wait_dropdown_open: true) - page.find('[data-qa-tab-id="meetings"]').click + global_search.open_tab :meetings expect(page.find_by_id("search-results")).to have_text(meeting.title) end @@ -62,7 +63,7 @@ RSpec.describe "Meeting search", :js do select_text: "In this project ↵", wait_dropdown_open: true) - page.find('[data-qa-tab-id="meetings"]').click + global_search.open_tab :meetings expect(page.find_by_id("search-results")).to have_text(meeting.title) end @@ -72,7 +73,7 @@ RSpec.describe "Meeting search", :js do select_text: "In this project ↵", wait_dropdown_open: true) - page.find('[data-qa-tab-id="meetings"]').click + global_search.open_tab :meetings expect(page.find_by_id("search-results")).to have_text(meeting.title) end end diff --git a/spec/features/search/search_spec.rb b/spec/features/search/search_spec.rb index 97d78037d07..26a6f3104bd 100644 --- a/spec/features/search/search_spec.rb +++ b/spec/features/search/search_spec.rb @@ -167,9 +167,11 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" # Selection project scope 'In all projects' redirects away from current project. global_search.submit_in_global_scope - expect(page) - .to have_current_path (/\/search/) - expect(current_url).to match(/\/search\?q=#{"%23#{search_target.id}"}&work_packages=1&scope=all$/) + expect(page).to have_current_path (/\/search/) + + expect(current_url).to include("q=#{"%23#{search_target.id}"}") + expect(current_url).to include("filter=work_packages") + expect(current_url).to include("scope=all") end end @@ -296,19 +298,12 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" global_search.submit_in_current_project # Expect that the "All" tab is selected. - expect(page).to have_css('[data-qa-tab-id="all"][data-qa-tab-selected]') + global_search.expect_active_tab :work_packages - # Expect that the project scope is set to current_project and no module (this is the "all" tab) is requested. - expect(current_url).to match(/\/#{project.identifier}\/search\?q=#{query}&scope=current_project$/) - - # Select "Work packages" tab - page.find('[data-qa-tab-id="work_packages"]').click - - # Expect that the project scope is set to current_project and the module "work_packages" is requested. - expect(current_url).to match(/\/search\?q=#{query}&work_packages=1&scope=current_project$/) - - # Expect that the "Work packages" tab is selected. - expect(page).to have_css('[data-qa-tab-id="work_packages"][data-qa-tab-selected]') + expect(current_url).to include("/#{project.identifier}/search") + expect(current_url).to include("q=#{query}") + expect(current_url).to include("filter=work_packages") + expect(current_url).to include("scope=current_project") table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container")) table.expect_work_package_count(5) # because we set the page size to this @@ -363,8 +358,9 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" # and expect that subproject's work packages will not be found table.ensure_work_package_not_listed! other_work_package - expect(current_url) - .to match(/\/#{project.identifier}\/search\?q=Other%20work%20package&work_packages=1&scope=current_project$/) + expect(current_url).to include("q=Other+work+package") + expect(current_url).to include("filter=work_packages") + expect(current_url).to include("scope=current_project") # Expect to find custom field values # ...for type: text @@ -381,12 +377,16 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" global_search.submit_in_project_and_subproject_scope # Expect that the "Work packages" tab is selected. - expect(page).to have_css('[data-qa-tab-id="work_packages"][data-qa-tab-selected]') + global_search.expect_active_tab :work_packages expect(page).to have_text "Search for \"#{other_work_package.subject}\" in #{project.name} and all subprojects" # Expect that the project scope is not set and work_packages module continues to stay selected. - expect(current_url).to match(/\/#{project.identifier}\/search\?q=Other%20work%20package&work_packages=1$/) + expect(current_url).to match(/\/#{project.identifier}\/search/) + expect(current_url).to include("q=Other+work+package") + expect(current_url).to include("filter=work_packages") + expect(current_url).to include("scope=&") + table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container")) table.expect_work_package_count(1) @@ -430,18 +430,21 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" global_search.search query global_search.submit_in_project_and_subproject_scope + global_search.open_tab :work_packages + + table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container")) + table.ensure_work_package_not_listed!(work_packages[0]) + table.ensure_work_package_not_listed!(work_packages[1]) + table.expect_work_package_listed(work_packages[9]) + + global_search.open_tab "All" + expect(page) .to have_content attachment_text expect(page) .to have_css(".search-highlight", text: query) - page.find('[data-qa-tab-id="work_packages"]').click - - table = Pages::EmbeddedWorkPackagesTable.new(find(".work-packages-embedded-view--container")) - table.ensure_work_package_not_listed!(work_packages[0]) - table.ensure_work_package_not_listed!(work_packages[1]) - table.expect_work_package_listed(work_packages[9]) end end end @@ -464,6 +467,7 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" it "highlights last note" do global_search.search "note" global_search.submit_in_global_scope + global_search.open_tab "All" within("dt.work_package-note + dd") do expect(page).to have_css(".description", text: note_two.notes) @@ -486,7 +490,7 @@ RSpec.describe "Search", :js, :selenium, with_settings: { per_page_options: "5" select_text: "In all projects ↵", wait_dropdown_open: false) - within ".global-search--tabs" do + within_test_selector("search-tabs") do click_on "Projects" end end diff --git a/spec/support/components/global_search.rb b/spec/support/components/global_search.rb index 379fb27953a..c0cbcbed941 100644 --- a/spec/support/components/global_search.rb +++ b/spec/support/components/global_search.rb @@ -43,6 +43,17 @@ module Components SeleniumHubWaiter.wait end + def open_tab(tab_id) + page.within_test_selector("search-tabs") do + name = tab_id.is_a?(Symbol) ? OpenProject::GlobalSearch.tab_name(tab_id.to_s) : tab_id + click_on(name) + end + end + + def expect_active_tab(id) + expect(page).to have_css("#{page.test_selector("search-tab-#{id}")}[aria-current]") + end + def expect_open expect(page).to have_selector(selector) end