From 0ed5fa1e8ea625d745ae0a32ddae0b20474bbce0 Mon Sep 17 00:00:00 2001 From: Olaf Alders Date: Sat, 3 May 2025 18:18:32 -0400 Subject: [PATCH 1/3] Add some aria roles to search form and search alert --- root/home.tx | 2 +- root/no_result.tx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/root/home.tx b/root/home.tx index b3f71c2a7e..edfbf12cc5 100644 --- a/root/home.tx +++ b/root/home.tx @@ -33,7 +33,7 @@ MetaCPAN

A search engine for CPAN

-
+
diff --git a/root/no_result.tx b/root/no_result.tx index 884129f751..1bb1c8f090 100644 --- a/root/no_result.tx +++ b/root/no_result.tx @@ -5,8 +5,8 @@

No search results for [% $search_query %]

%% if $suggest { -
- Did you mean : + %% } From a118da8def6d3ab86463cfd5e5553fb3708a6937 Mon Sep 17 00:00:00 2001 From: Olaf Alders Date: Sat, 3 May 2025 18:18:50 -0400 Subject: [PATCH 2/3] Fix suggestion handling when there's a search prefix --- e2e/home.spec.ts | 50 ++++++++++++++++++++++++--- lib/MetaCPAN/Web/Controller/Search.pm | 8 +++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/e2e/home.spec.ts b/e2e/home.spec.ts index de6db7db7c..1beba3ec10 100644 --- a/e2e/home.spec.ts +++ b/e2e/home.spec.ts @@ -1,6 +1,48 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from "@playwright/test"; -test('home page', async ({ page }) => { - await page.goto('/'); - await expect(page).toHaveTitle(/Search the CPAN - metacpan.org/, { timeout: 10 }); +test("home page", async ({ page }) => { + await page.goto("/"); + await expect(page).toHaveTitle(/Search the CPAN - metacpan.org/, { + timeout: 10, + }); +}); + +test("suggest is correct", async ({ page }) => { + await page.goto("/"); + const searchInput = page.getByPlaceholder("Search the CPAN"); + await expect(searchInput).toBeVisible(); + searchInput.fill("HTML:Restrict"); + await searchInput.press("Enter"); + + await expect(page.getByRole('alert')).toContainText('Did you mean: HTML::Restrict'); +}); + +test("suggest accounts for prefix and makes suggestion", async ({ page }) => { + await page.goto("/"); + const searchInput = page.getByPlaceholder("Search the CPAN"); + await expect(searchInput).toBeVisible(); + searchInput.fill("distribution:HTML:Restrict"); + await searchInput.press("Enter"); + + await expect(page.getByRole('alert')).toContainText('Did you mean: distribution:HTML::Restrict'); +}); + +test("suggest accounts for prefix but cannot make suggestion", async ({ page }) => { + await page.goto("/"); + const searchInput = page.getByPlaceholder("Search the CPAN"); + await expect(searchInput).toBeVisible(); + searchInput.fill("distribution:HTMLRestrict"); + await searchInput.press("Enter"); + + await expect(page.getByRole('alert')).toBeHidden(); +}); + +test("suggest ignores misspelled prefix and makes suggestion", async ({ page }) => { + await page.goto("/"); + const searchInput = page.getByPlaceholder("Search the CPAN"); + await expect(searchInput).toBeVisible(); + searchInput.fill("disstribution:HTML:Restrict"); + await searchInput.press("Enter"); + + await expect(page.getByRole('alert')).toContainText('Did you mean: disstribution::HTML::Restrict'); }); diff --git a/lib/MetaCPAN/Web/Controller/Search.pm b/lib/MetaCPAN/Web/Controller/Search.pm index 9754e43066..37b10bb07f 100644 --- a/lib/MetaCPAN/Web/Controller/Search.pm +++ b/lib/MetaCPAN/Web/Controller/Search.pm @@ -84,10 +84,14 @@ sub index : Path : Args(0) { if ( !$results->{total} && !$authors->{total} ) { my $suggest = $query; + my $prefix = q{}; + if ( $suggest =~ s{^(author|distribution|module|version):}{} ) { + $prefix = $1 . ':'; + } $suggest =~ s/\s*:+\s*/::/g; - if ( $suggest ne $query ) { + if ( $prefix . $suggest ne $query ) { $c->stash( { - suggest => $suggest, + suggest => $prefix . $suggest, } ); } $c->stash( { From a0b2f4d746dd5609c1f2ad56dfd26560ad008e1f Mon Sep 17 00:00:00 2001 From: Olaf Alders Date: Sun, 4 May 2025 03:34:57 -0400 Subject: [PATCH 3/3] Try to enable coverage in playwright testing --- .github/workflows/test.yml | 36 +++++++++++++++++++++++++++++++----- Dockerfile | 15 +++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 66c057811d..8dace3329d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -68,23 +68,49 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build test image - id: docker-build-test + id: docker-build-playwright uses: docker/build-push-action@v6 with: - target: server + target: playwright push: false load: true - - name: Run Perl tests + - name: Start playwright server + id: start-container run: > - docker run -d -i -p 8000:80 - ${{ steps.docker-build-test.outputs.imageid }} + CONTAINER_ID=$(docker run -d -i -p 8000:80 + -v $(pwd):/app + ${{ steps.docker-build-playwright.outputs.imageid }}) + && echo "container_id=$CONTAINER_ID" >> $GITHUB_OUTPUT + || (echo "Failed to start container" && exit 1) - uses: actions/setup-node@v4 with: node-version: 22 - name: Install Playwright Browsers run: ./bin/install-playwright + - name: Install Codecovbash + uses: perl-actions/install-with-cpm@v1 + with: + install: | + Devel::Cover + Devel::Cover::Report::Codecovbash + sudo: true + - name: Check docker status + id: playwright-tests + run: | + npx playwright test || { + echo "Playwright tests failed" + docker logs ${{ steps.start-container.outputs.container_id }} + exit 1 + } - name: Run Playwright tests run: npx playwright test + - name: Generate Codecov report + run: cover -report codecovbash + - uses: codecov/codecov-action@v5 + with: + fail_ci_if_error: true + file: ./cover_db/codecov.json + token: ${{ secrets.CODECOV_TOKEN }} test: runs-on: ubuntu-24.04 name: Dockerless diff --git a/Dockerfile b/Dockerfile index de1ab83000..d19218545f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -123,3 +123,18 @@ CMD [ "prove", "-l", "-r", "-j", "2", "t" ] FROM server AS production USER metacpan + +################### Playwright Server +FROM server AS playwright +USER root + +RUN echo "Starting Playwright stage setup" +RUN --mount=type=cache,target=/root/.perl-cpm,sharing=private \ +<