refactor(e2e): test urls can have trailing slashes (#58283)

This commit is contained in:
Oliver Eyton-Williams
2025-01-24 00:04:35 +01:00
committed by GitHub
parent 4eef3854c7
commit 8a852719f1
9 changed files with 24 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json'; import translations from '../client/i18n/locales/english/translations.json';
import { authedRequest } from './utils/request'; import { authedRequest } from './utils/request';
import { allowTrailingSlash } from './utils/url';
const nextChallengeURL = const nextChallengeURL =
'/learn/data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer'; '/learn/data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer';
@@ -72,7 +73,7 @@ test.describe('Challenge Completion Modal Tests (Signed Out)', () => {
await page await page
.getByRole('link', { name: translations.learn['sign-in-save'] }) .getByRole('link', { name: translations.learn['sign-in-save'] })
.click(); .click();
await expect(page).toHaveURL(/.*\/learn\/?$/); await expect(page).toHaveURL(allowTrailingSlash('/learn'));
}); });
test('should redirect to next challenge', async ({ page }) => { test('should redirect to next challenge', async ({ page }) => {

View File

@@ -5,6 +5,7 @@ import { test, expect } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json'; import translations from '../client/i18n/locales/english/translations.json';
import { alertToBeVisible } from './utils/alerts'; import { alertToBeVisible } from './utils/alerts';
import { allowTrailingSlash } from './utils/url';
const execP = promisify(exec); const execP = promisify(exec);
@@ -145,7 +146,7 @@ test.describe('Delete Modal component', () => {
}) })
).not.toBeVisible(); ).not.toBeVisible();
await expect(page).toHaveURL(/.*\/learn\/?/); await expect(page).toHaveURL(allowTrailingSlash('/learn'));
await alertToBeVisible(page, translations.flash['account-deleted']); await alertToBeVisible(page, translations.flash['account-deleted']);
// The user is signed out after their account is deleted // The user is signed out after their account is deleted
await expect(page.getByRole('link', { name: 'Sign in' })).toHaveCount(2); await expect(page.getByRole('link', { name: 'Sign in' })).toHaveCount(2);

View File

@@ -3,6 +3,7 @@ import { test, expect, type Page } from '@playwright/test';
import { addGrowthbookCookie } from './utils/add-growthbook-cookie'; import { addGrowthbookCookie } from './utils/add-growthbook-cookie';
import { clearEditor, focusEditor } from './utils/editor'; import { clearEditor, focusEditor } from './utils/editor';
import { allowTrailingSlash } from './utils/url';
const slowExpect = expect.configure({ timeout: 25000 }); const slowExpect = expect.configure({ timeout: 25000 });
@@ -22,7 +23,9 @@ const completeFrontEndCert = async (page: Page, number?: number) => {
const loopNumber = number || projects.length; const loopNumber = number || projects.length;
for (let i = 0; i < loopNumber; i++) { for (let i = 0; i < loopNumber; i++) {
await page.waitForURL( await page.waitForURL(
`/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-${projects[i]}` allowTrailingSlash(
`/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-${projects[i]}`
)
); );
await page await page
.getByRole('textbox', { name: 'solution' }) .getByRole('textbox', { name: 'solution' })
@@ -92,7 +95,7 @@ const completeChallenges = async ({
}) => { }) => {
await page.goto(challenges[0].url); await page.goto(challenges[0].url);
for (const challenge of challenges.slice(0, number)) { for (const challenge of challenges.slice(0, number)) {
await page.waitForURL(challenge.url); await page.waitForURL(allowTrailingSlash(challenge.url));
await focusEditor({ page, isMobile }); await focusEditor({ page, isMobile });
await clearEditor({ page, browserName }); await clearEditor({ page, browserName });
await page.evaluate( await page.evaluate(

View File

@@ -3,6 +3,7 @@ import { execSync } from 'child_process';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json'; import translations from '../client/i18n/locales/english/translations.json';
import { allowTrailingSlash } from './utils/url';
const apiLocation = process.env.API_LOCATION || 'http://localhost:3000'; const apiLocation = process.env.API_LOCATION || 'http://localhost:3000';
@@ -73,7 +74,7 @@ test.describe('Email sign-up page when user is not signed in', () => {
// The user is signed in and automatically redirected to /learn after clicking the button. // The user is signed in and automatically redirected to /learn after clicking the button.
// We wait for this navigation to complete before moving onto the next. // We wait for this navigation to complete before moving onto the next.
await page.waitForURL('**/learn'); await page.waitForURL(allowTrailingSlash('/learn'));
await expect( await expect(
page.getByRole('heading', { name: 'Welcome back, Full Stack User' }) page.getByRole('heading', { name: 'Welcome back, Full Stack User' })
).toBeVisible(); ).toBeVisible();
@@ -144,7 +145,7 @@ test.describe('Email sign-up page when user is signed in', () => {
// The user is signed in and automatically redirected to /learn after clicking the button. // The user is signed in and automatically redirected to /learn after clicking the button.
// We wait for the navigation to complete. // We wait for the navigation to complete.
await page.waitForURL('**/learn'); await page.waitForURL('/learn');
await expect( await expect(
page.getByRole('heading', { name: 'Welcome back, Full Stack User' }) page.getByRole('heading', { name: 'Welcome back, Full Stack User' })
).toBeVisible(); ).toBeVisible();
@@ -180,7 +181,7 @@ test.describe('Email sign-up page when user is signed in', () => {
// The user is signed in and automatically redirected to /learn after clicking the button. // The user is signed in and automatically redirected to /learn after clicking the button.
// We wait for the navigation to complete. // We wait for the navigation to complete.
await page.waitForURL('**/learn'); await page.waitForURL('/learn');
await expect( await expect(
page.getByRole('heading', { name: 'Welcome back, Full Stack User' }) page.getByRole('heading', { name: 'Welcome back, Full Stack User' })
).toBeVisible(); ).toBeVisible();

View File

@@ -1,4 +1,5 @@
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { allowTrailingSlash } from './utils/url';
test.describe('Quiz challenge', () => { test.describe('Quiz challenge', () => {
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
@@ -66,7 +67,9 @@ test.describe('Quiz challenge', () => {
// The navigation should be blocked, the user should stay on the same page // The navigation should be blocked, the user should stay on the same page
await expect(page).toHaveURL( await expect(page).toHaveURL(
'/learn/full-stack-developer/quiz-basic-html/quiz-basic-html' allowTrailingSlash(
'/learn/full-stack-developer/quiz-basic-html/quiz-basic-html'
)
); );
await expect(page.getByRole('dialog')).toBeVisible(); await expect(page.getByRole('dialog')).toBeVisible();

View File

@@ -1,4 +1,5 @@
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { allowTrailingSlash } from './utils/url';
// To run this test locally you will need to run: pnpm run start-ci; // To run this test locally you will need to run: pnpm run start-ci;
// Also, make sure that you have pm2 installed globally via: pnpm install -g pm2 // Also, make sure that you have pm2 installed globally via: pnpm install -g pm2
@@ -74,7 +75,7 @@ test.describe('Legacy Challenge Path Redirection Tests', () => {
for (const [input, expected] of pathsToTest) { for (const [input, expected] of pathsToTest) {
test(`should redirect from ${input} to ${expected}`, async ({ page }) => { test(`should redirect from ${input} to ${expected}`, async ({ page }) => {
await page.goto(input); await page.goto(input);
await expect(page).toHaveURL(new RegExp(`${expected}/?`)); await expect(page).toHaveURL(allowTrailingSlash(expected));
}); });
} }
}); });

View File

@@ -1,5 +1,6 @@
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json'; import translations from '../client/i18n/locales/english/translations.json';
import { allowTrailingSlash } from './utils/url';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
@@ -49,7 +50,7 @@ test.describe('Signout Modal component', () => {
await expect( await expect(
page.getByRole('dialog', { name: translations.signout.heading }) page.getByRole('dialog', { name: translations.signout.heading })
).not.toBeVisible(); ).not.toBeVisible();
await expect(page).toHaveURL(/.*\/learn\/?$/); await expect(page).toHaveURL(allowTrailingSlash('/learn'));
}); });
test('closes modal after user cancels signing out', async ({ page }) => { test('closes modal after user cancels signing out', async ({ page }) => {

View File

@@ -1,5 +1,6 @@
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import translations from '../client/i18n/locales/english/translations.json'; import translations from '../client/i18n/locales/english/translations.json';
import { allowTrailingSlash } from './utils/url';
test.describe('The update-email page when the user is signed in', () => { test.describe('The update-email page when the user is signed in', () => {
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
@@ -64,7 +65,7 @@ test.describe('The update-email page when the user is not signed in', () => {
// Ref: https://github.com/microsoft/playwright/issues/20749 // Ref: https://github.com/microsoft/playwright/issues/20749
test.skip(browserName === 'firefox'); test.skip(browserName === 'firefox');
await page.waitForURL(/\/learn\/?/); await page.waitForURL(allowTrailingSlash('/learn'));
await expect( await expect(
page.getByRole('heading', { name: 'Welcome back, Full Stack User' }) page.getByRole('heading', { name: 'Welcome back, Full Stack User' })

1
e2e/utils/url.ts Normal file
View File

@@ -0,0 +1 @@
export const allowTrailingSlash = (url: string) => RegExp(url + '[/]?$');