diff --git a/test/apps/angular-app/main.ts b/test/apps/angular-app/main.ts index 0779c2423d..21a57e7bde 100644 --- a/test/apps/angular-app/main.ts +++ b/test/apps/angular-app/main.ts @@ -27,11 +27,11 @@ if (window.RUM_CONTEXT) { imports: [RouterLink], template: `

Initial Route

- Go to User 42
- Go to Guides 123
- Go to Error Test
- Go to Nested Route
- Go to Wildcard Route
+ Go to User 42
+ Go to Guides 123
+ Go to Error Test
+ Go to Nested Route
+ Go to Wildcard Route
`, @@ -54,10 +54,14 @@ class InitialRouteComponent { imports: [RouterLink], template: `

User Page

- Back to Home
- Go to Section
- Change query params
- Go to User 999 + Back to Home
+ Go to Section
+ Change query params
+ Go to User 999 `, }) class UserRouteComponent { @@ -70,7 +74,7 @@ class UserRouteComponent { imports: [RouterLink], template: `

Guides

- Back to Home + Back to Home `, }) class GuidesRouteComponent {} diff --git a/test/apps/nextjs/app/guides/[...slug]/page.tsx b/test/apps/nextjs/app/guides/[...slug]/page.tsx index 0b9003d978..6e4f2931fa 100644 --- a/test/apps/nextjs/app/guides/[...slug]/page.tsx +++ b/test/apps/nextjs/app/guides/[...slug]/page.tsx @@ -5,7 +5,9 @@ export default async function GuidesPage({ params }: { params: Promise<{ slug: s return (
- Back to Home + + Back to Home +

Guides: {slug.join('/')}

) diff --git a/test/apps/nextjs/app/page.tsx b/test/apps/nextjs/app/page.tsx index 9d80fd5b82..42e978560f 100644 --- a/test/apps/nextjs/app/page.tsx +++ b/test/apps/nextjs/app/page.tsx @@ -6,19 +6,29 @@ export default function HomePage() {

Home

diff --git a/test/apps/nextjs/app/user/[id]/page.tsx b/test/apps/nextjs/app/user/[id]/page.tsx index d3832f7cf0..6f1dc8eaba 100644 --- a/test/apps/nextjs/app/user/[id]/page.tsx +++ b/test/apps/nextjs/app/user/[id]/page.tsx @@ -5,16 +5,24 @@ export default async function UserPage({ params }: { params: Promise<{ id: strin return (
- ← Back to Home + + ← Back to Home +

User {id}

- Go to User 999 + + Go to User 999 +
- Change query params + + Change query params +
- Go to Section + + Go to Section +
) diff --git a/test/apps/nextjs/pages/pages-router/guides/[...slug].tsx b/test/apps/nextjs/pages/pages-router/guides/[...slug].tsx index e54ea7d828..f406a1cc26 100644 --- a/test/apps/nextjs/pages/pages-router/guides/[...slug].tsx +++ b/test/apps/nextjs/pages/pages-router/guides/[...slug].tsx @@ -8,7 +8,9 @@ export default function GuidesPage() { return (
- ← Back to Home + + ← Back to Home +

Guides: {slugParts.join('/')}

) diff --git a/test/apps/nextjs/pages/pages-router/index.tsx b/test/apps/nextjs/pages/pages-router/index.tsx index 2d31b81838..b64c2730b5 100644 --- a/test/apps/nextjs/pages/pages-router/index.tsx +++ b/test/apps/nextjs/pages/pages-router/index.tsx @@ -6,13 +6,19 @@ export default function HomePage() {

Home

diff --git a/test/apps/nextjs/pages/pages-router/user/[id].tsx b/test/apps/nextjs/pages/pages-router/user/[id].tsx index 929a5104d2..e276e76042 100644 --- a/test/apps/nextjs/pages/pages-router/user/[id].tsx +++ b/test/apps/nextjs/pages/pages-router/user/[id].tsx @@ -7,16 +7,24 @@ export default function UserPage() { return (
- ← Back to Home + + ← Back to Home +

User {id}

- Go to User 999 + + Go to User 999 +
- Change query params + + Change query params +
- Go to Section + + Go to Section +
) diff --git a/test/apps/nuxt-app/pages/guides/[...slug].vue b/test/apps/nuxt-app/pages/guides/[...slug].vue index 9e5817691b..57dbfb70dd 100644 --- a/test/apps/nuxt-app/pages/guides/[...slug].vue +++ b/test/apps/nuxt-app/pages/guides/[...slug].vue @@ -1,6 +1,6 @@ diff --git a/test/apps/nuxt-app/pages/index.vue b/test/apps/nuxt-app/pages/index.vue index 4669277f20..47ea1f3007 100644 --- a/test/apps/nuxt-app/pages/index.vue +++ b/test/apps/nuxt-app/pages/index.vue @@ -1,8 +1,8 @@ diff --git a/test/apps/nuxt-app/pages/user/[id].vue b/test/apps/nuxt-app/pages/user/[id].vue index 22c76dd2f8..39c2088ea4 100644 --- a/test/apps/nuxt-app/pages/user/[id].vue +++ b/test/apps/nuxt-app/pages/user/[id].vue @@ -5,9 +5,11 @@ const route = useRoute() diff --git a/test/apps/nuxt-app/yarn.lock b/test/apps/nuxt-app/yarn.lock index 3f5c01f111..c8998634d4 100644 --- a/test/apps/nuxt-app/yarn.lock +++ b/test/apps/nuxt-app/yarn.lock @@ -347,8 +347,8 @@ __metadata: "@datadog/browser-core@file:../../../packages/core/package.tgz::locator=nuxt-app%40workspace%3A.": version: 6.32.0 - resolution: "@datadog/browser-core@file:../../../packages/core/package.tgz#../../../packages/core/package.tgz::hash=3139c3&locator=nuxt-app%40workspace%3A." - checksum: 10c0/043726d1ed47fc37dc7f38bf1a79db8ddc191eb07602e347e96d02c4f837d5773ed548dd8c07a8e92f121d460da68d84088489030c7f88120194927c77b4ac09 + resolution: "@datadog/browser-core@file:../../../packages/core/package.tgz#../../../packages/core/package.tgz::hash=2bcbab&locator=nuxt-app%40workspace%3A." + checksum: 10c0/d184c9c1b22336ceebe73f9e7b74c1d8fc955610171d9d765e2032baf4ce3fc1b63bea4950a0bd99a73e212d75e064b9161dad6df9cefdaf8fdbe54d4ad29ecd languageName: node linkType: hard @@ -363,7 +363,7 @@ __metadata: "@datadog/browser-rum-nuxt@file:../../../packages/rum-nuxt/package.tgz::locator=nuxt-app%40workspace%3A.": version: 0.0.0 - resolution: "@datadog/browser-rum-nuxt@file:../../../packages/rum-nuxt/package.tgz#../../../packages/rum-nuxt/package.tgz::hash=e895b3&locator=nuxt-app%40workspace%3A." + resolution: "@datadog/browser-rum-nuxt@file:../../../packages/rum-nuxt/package.tgz#../../../packages/rum-nuxt/package.tgz::hash=293201&locator=nuxt-app%40workspace%3A." dependencies: "@datadog/browser-core": "npm:6.32.0" "@datadog/browser-rum-core": "npm:6.32.0" @@ -382,7 +382,7 @@ __metadata: optional: true vue-router: optional: true - checksum: 10c0/8c760e9dbd337296a5f4d55980616dc37a47b98676887e7db50aa8ff6cb70b7979ae647229c58daeea9bf3053eb1fc701e637e8c4783aacb9eedc769bb994383 + checksum: 10c0/ee8d7b559120abea1056e7c984e731cd9cac8edf83d8840bcbabd65e9f0fb51725f9a7ccbab22a396cd73116964091067aaa09e36d2ea0e2113548c89ddeba9a languageName: node linkType: hard diff --git a/test/apps/react-router-v6-app/app.tsx b/test/apps/react-router-v6-app/app.tsx index e0f9aea8f1..3da3afd722 100644 --- a/test/apps/react-router-v6-app/app.tsx +++ b/test/apps/react-router-v6-app/app.tsx @@ -25,15 +25,25 @@ function HomePage() { return (

Home

- Go to User 42 + + Go to User 42 +
- Go to Guides 123 + + Go to Guides 123 +
- Go to Wildcard + + Go to Wildcard +
- Go to Error Test + + Go to Error Test +
- Go to Tracked + + Go to Tracked +
) } @@ -43,13 +53,21 @@ function UserPage() { return (

User {id}

- Back to Home + + Back to Home +
- Go to Section + + Go to Section +
- Change query params + + Change query params +
- Go to User 999 + + Go to User 999 +
) } @@ -58,7 +76,9 @@ function GuidesPage() { return (

Guides

- Back to Home + + Back to Home +
) } @@ -68,7 +88,9 @@ function WildcardPage() { return (

Wildcard: {splatPath}

- Back to Home + + Back to Home +
) } diff --git a/test/apps/vue-router-app/src/pages/GuidesPage.vue b/test/apps/vue-router-app/src/pages/GuidesPage.vue index 175e982d4f..545da0153e 100644 --- a/test/apps/vue-router-app/src/pages/GuidesPage.vue +++ b/test/apps/vue-router-app/src/pages/GuidesPage.vue @@ -1,6 +1,6 @@ diff --git a/test/apps/vue-router-app/src/pages/HomePage.vue b/test/apps/vue-router-app/src/pages/HomePage.vue index 6fae5a7ea1..3c4f64a664 100644 --- a/test/apps/vue-router-app/src/pages/HomePage.vue +++ b/test/apps/vue-router-app/src/pages/HomePage.vue @@ -1,8 +1,8 @@ diff --git a/test/apps/vue-router-app/src/pages/UserPage.vue b/test/apps/vue-router-app/src/pages/UserPage.vue index 3dcd166c10..b342791dc3 100644 --- a/test/apps/vue-router-app/src/pages/UserPage.vue +++ b/test/apps/vue-router-app/src/pages/UserPage.vue @@ -5,9 +5,11 @@ const route = useRoute() diff --git a/test/e2e/scenario/browser-extensions/browserExtensions.scenario.ts b/test/e2e/scenario/browser-extensions/browserExtensions.scenario.ts index 0bb5b571cd..f894f4f89f 100644 --- a/test/e2e/scenario/browser-extensions/browserExtensions.scenario.ts +++ b/test/e2e/scenario/browser-extensions/browserExtensions.scenario.ts @@ -92,7 +92,7 @@ test.describe('browser extensions', () => { */ createTest('should not warn - edge case simulating NextJs with an extension that override `appendChild`') .withExtension(createExtension(path.join(BASE_PATH, 'appendChild-extension'))) - .withRum() + .withRum({ sessionReplaySampleRate: 0 }) .withLogs() .withSetup((options, servers) => { const { rumScriptUrl, logsScriptUrl } = createCrossOriginScriptUrls(servers, options) diff --git a/test/e2e/scenario/plugins/angularPlugin.scenario.ts b/test/e2e/scenario/plugins/angularPlugin.scenario.ts index 89bc229b69..1fbad247a6 100644 --- a/test/e2e/scenario/plugins/angularPlugin.scenario.ts +++ b/test/e2e/scenario/plugins/angularPlugin.scenario.ts @@ -1,7 +1,8 @@ import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' import { runBasePluginErrorTests } from './basePluginErrorTests' -import { runBasePluginRouterTests } from './basePluginRouterTests' +import { createBasePluginRouterConfig, runBasePluginRouterTests } from './basePluginRouterTests' +import { clickAndWaitForURL } from './navigationUtils' const angularAppName = 'angular-app' const angularBasePluginConfig = { @@ -13,12 +14,13 @@ const angularBasePluginConfig = { runBasePluginRouterTests([ { ...angularBasePluginConfig, - router: { + router: createBasePluginRouterConfig({ homeViewName: '/', homeUrlPattern: '**/', userRouteName: '/user/:id', guidesRouteName: '/guides/:slug', - }, + viewPrefix: '', + }), }, ]) @@ -38,26 +40,28 @@ test.describe('plugin: angular', () => { .withRum() .withApp(angularAppName) .run(async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to Nested Route') + await clickAndWaitForURL(page, '[data-testid="go-to-nested-route"]', '**/parent/nested') await flushEvents() - const viewEvents = intakeRegistry.rumViewEvents - expect(viewEvents.length).toBeGreaterThan(0) - const lastView = viewEvents[viewEvents.length - 1] - expect(lastView.view.name).toBe('/parent/nested') - expect(lastView.view.url).toContain('/parent/nested') + + const nestedView = intakeRegistry.rumViewEvents.find( + (event) => event.view.name === '/parent/nested' && event.view.url?.includes('/parent/nested') + ) + expect(nestedView).toBeDefined() + expect(nestedView?.view.url).toContain('/parent/nested') }) createTest('should define a view name with the actual path for wildcard routes') .withRum() .withApp(angularAppName) .run(async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to Wildcard Route') + await clickAndWaitForURL(page, '[data-testid="go-to-wildcard"]', '**/unknown/page') await flushEvents() - const viewEvents = intakeRegistry.rumViewEvents - expect(viewEvents.length).toBeGreaterThan(0) - const lastView = viewEvents[viewEvents.length - 1] - expect(lastView.view.name).toBe('/unknown/page') - expect(lastView.view.url).toContain('/unknown/page') + + const wildcardView = intakeRegistry.rumViewEvents.find( + (event) => event.view.name === '/unknown/page' && event.view.url?.includes('/unknown/page') + ) + expect(wildcardView).toBeDefined() + expect(wildcardView?.view.url).toContain('/unknown/page') }) createTest('should report errors caught by provideDatadogErrorHandler') diff --git a/test/e2e/scenario/plugins/basePluginErrorTests.ts b/test/e2e/scenario/plugins/basePluginErrorTests.ts index 3f709c6b41..644b1c8233 100644 --- a/test/e2e/scenario/plugins/basePluginErrorTests.ts +++ b/test/e2e/scenario/plugins/basePluginErrorTests.ts @@ -1,5 +1,6 @@ import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' +import { clickAndWait, clickAndWaitForURL } from './navigationUtils' type TestBuilder = ReturnType @@ -8,6 +9,7 @@ interface ErrorConfig { expectedFramework: string expectsBrowserConsoleErrors?: boolean expectsComponentStack?: boolean + errorHandledSelector?: string } interface ErrorPluginTestConfig { @@ -23,11 +25,16 @@ export function runBasePluginErrorTests(configs: ErrorPluginTestConfig[]) { test.describe('errors', () => { loadApp(createTest('should report client-side error').withRum()).run( async ({ page, flushEvents, intakeRegistry, withBrowserLogs }) => { - await page.click('text=Go to Error Test') - await page.waitForURL(`**${viewPrefix}/error-test`) - - await page.click('[data-testid="trigger-error"]') - await page.waitForSelector('[data-testid="error-handled"]') + await clickAndWaitForURL( + page, + '[data-testid="go-to-error-test"]', + `**${viewPrefix}/error-test`, + '[data-testid="trigger-error"]' + ) + + await clickAndWait(page, '[data-testid="trigger-error"]', { + readySelector: error.errorHandledSelector ?? '[data-testid="error-handled"]', + }) await flushEvents() diff --git a/test/e2e/scenario/plugins/basePluginRouterTests.ts b/test/e2e/scenario/plugins/basePluginRouterTests.ts index 4aa8978477..07032e31a6 100644 --- a/test/e2e/scenario/plugins/basePluginRouterTests.ts +++ b/test/e2e/scenario/plugins/basePluginRouterTests.ts @@ -1,13 +1,26 @@ +import type { Page } from '@playwright/test' import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' +import type { NavigationTarget, UrlPattern } from './navigationUtils' +import { clickAndWaitForURL, goHome } from './navigationUtils' type TestBuilder = ReturnType +interface RouteNavigation extends NavigationTarget { + urlPattern: UrlPattern +} + interface RouterConfig { homeViewName: string - homeUrlPattern: string | RegExp + homeNavigation: RouteNavigation userRouteName: string guidesRouteName: string + navigation: { + guides: RouteNavigation + user: RouteNavigation + queryChange: RouteNavigation + otherUser: RouteNavigation + } } interface RouterPluginTestConfig { @@ -17,9 +30,76 @@ interface RouterPluginTestConfig { router: RouterConfig } +interface RouteFixtures { + guideSlug: string + userId: string + otherUserId: string +} + +interface CreateBasePluginRouterConfigParams { + homeViewName: string + homeUrlPattern: UrlPattern + userRouteName: string + guidesRouteName: string + viewPrefix: string + fixtures?: Partial +} + +const DEFAULT_ROUTE_FIXTURES: RouteFixtures = { + guideSlug: '123', + userId: '42', + otherUserId: '999', +} + +export function createBasePluginRouterConfig({ + homeViewName, + homeUrlPattern, + userRouteName, + guidesRouteName, + viewPrefix, + fixtures, +}: CreateBasePluginRouterConfigParams): RouterConfig { + const { guideSlug, userId, otherUserId } = { ...DEFAULT_ROUTE_FIXTURES, ...fixtures } + + return { + homeViewName, + homeNavigation: { + clickSelector: '[data-testid="back-to-home"]', + urlPattern: homeUrlPattern, + readySelector: '[data-testid="go-to-user"]', + }, + userRouteName, + guidesRouteName, + navigation: { + guides: { + clickSelector: '[data-testid="go-to-guides"]', + urlPattern: `**${viewPrefix}/guides/${guideSlug}`, + readySelector: '[data-testid="back-to-home"]', + }, + user: { + clickSelector: '[data-testid="go-to-user"]', + urlPattern: `**${viewPrefix}/user/${userId}?admin=true`, + readySelector: '[data-testid="back-to-home"]', + }, + queryChange: { + clickSelector: '[data-testid="change-query-params"]', + urlPattern: `**${viewPrefix}/user/${userId}?admin=false`, + }, + otherUser: { + clickSelector: '[data-testid="go-to-other-user"]', + urlPattern: `**${viewPrefix}/user/${otherUserId}?admin=true`, + }, + }, + } +} + +async function clickAndWaitForNavigation(page: Page, navigation: RouteNavigation) { + await clickAndWaitForURL(page, navigation.clickSelector, navigation.urlPattern, navigation.readySelector) +} + export function runBasePluginRouterTests(configs: RouterPluginTestConfig[]) { for (const { name, loadApp, viewPrefix, router } of configs) { - const { homeViewName, homeUrlPattern, userRouteName, guidesRouteName } = router + const { homeViewName, homeNavigation, userRouteName, guidesRouteName, navigation } = router test.describe(`base plugin: ${name}`, () => { test.describe('router', () => { @@ -28,9 +108,10 @@ export function runBasePluginRouterTests(configs: RouterPluginTestConfig[]) { const viewEvents = intakeRegistry.rumViewEvents expect(viewEvents.length).toBeGreaterThan(0) - const firstView = viewEvents[0] - expect(firstView.view.name).toBe(homeViewName) - expect(firstView.view.loading_type).toBe('initial_load') + const initialHomeView = viewEvents.find( + (e) => e.view.name === homeViewName && e.view.loading_type === 'initial_load' + ) + expect(initialHomeView).toBeDefined() }) loadApp(createTest('should normalize dynamic routes and preserve real URLs and referrers').withRum()).run( @@ -38,17 +119,13 @@ export function runBasePluginRouterTests(configs: RouterPluginTestConfig[]) { const baseOrigin = new URL(baseUrl).origin // Home → Guides → Home → User → Home - await page.click('text=Go to Guides 123') - await page.waitForURL('**/guides/123') + await clickAndWaitForNavigation(page, navigation.guides) - await page.click('text=Back to Home') - await page.waitForURL(homeUrlPattern) + await goHome(page, homeNavigation) - await page.click('text=Go to User 42') - await page.waitForURL('**/user/42?admin=true') + await clickAndWaitForNavigation(page, navigation.user) - await page.click('text=Back to Home') - await page.waitForURL(homeUrlPattern) + await goHome(page, homeNavigation) await flushEvents() @@ -74,11 +151,9 @@ export function runBasePluginRouterTests(configs: RouterPluginTestConfig[]) { loadApp(createTest('should track SPA navigation with loading_time').withRum()).run( async ({ page, flushEvents, intakeRegistry }) => { await page.waitForLoadState('networkidle') - await page.click('text=Go to User 42') - await page.waitForURL('**/user/42?admin=true') + await clickAndWaitForNavigation(page, navigation.user) - await page.click('text=Back to Home') - await page.waitForURL(homeUrlPattern) + await goHome(page, homeNavigation) await flushEvents() @@ -95,14 +170,9 @@ export function runBasePluginRouterTests(configs: RouterPluginTestConfig[]) { loadApp(createTest('should not create a new view when query params change').withRum()).run( async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to User 42') - await page.waitForURL('**/user/42?admin=true') + await clickAndWaitForNavigation(page, navigation.user) - await page.click('text=Change query params') - await page.waitForURL('**/user/42?admin=false') - - await page.click('text=Back to Home') - await page.waitForURL(homeUrlPattern) + await clickAndWaitForNavigation(page, navigation.queryChange) await flushEvents() @@ -117,14 +187,9 @@ export function runBasePluginRouterTests(configs: RouterPluginTestConfig[]) { loadApp( createTest('should track navigations between different concrete URLs of the same dynamic route').withRum() ).run(async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to User 42') - await page.waitForURL('**/user/42?admin=true') - - await page.click('text=Go to User 999') - await page.waitForURL('**/user/999?admin=true') + await clickAndWaitForNavigation(page, navigation.user) - await page.click('text=Back to Home') - await page.waitForURL(homeUrlPattern) + await clickAndWaitForNavigation(page, navigation.otherUser) await flushEvents() diff --git a/test/e2e/scenario/plugins/navigationUtils.ts b/test/e2e/scenario/plugins/navigationUtils.ts new file mode 100644 index 0000000000..80b56c3dba --- /dev/null +++ b/test/e2e/scenario/plugins/navigationUtils.ts @@ -0,0 +1,40 @@ +import type { Page } from '@playwright/test' + +export type UrlPattern = string | RegExp + +interface ClickAndWaitOptions { + urlPattern?: UrlPattern + readySelector?: string +} + +export interface NavigationTarget extends ClickAndWaitOptions { + clickSelector: string +} + +export async function clickAndWait( + page: Page, + selector: string, + { urlPattern, readySelector }: ClickAndWaitOptions = {} +) { + if (urlPattern !== undefined) { + await Promise.all([page.waitForURL(urlPattern), page.click(selector)]) + } else { + await page.click(selector) + } + + if (readySelector) { + await page.waitForSelector(readySelector) + } +} + +export async function navigate(page: Page, navigation: NavigationTarget) { + await clickAndWait(page, navigation.clickSelector, navigation) +} + +export async function clickAndWaitForURL(page: Page, selector: string, urlPattern: UrlPattern, readySelector?: string) { + await clickAndWait(page, selector, { urlPattern, readySelector }) +} + +export async function goHome(page: Page, homeNavigation: NavigationTarget) { + await navigate(page, homeNavigation) +} diff --git a/test/e2e/scenario/plugins/nextjsPlugin.scenario.ts b/test/e2e/scenario/plugins/nextjsPlugin.scenario.ts index 9dcd70e1b3..fa251e025b 100644 --- a/test/e2e/scenario/plugins/nextjsPlugin.scenario.ts +++ b/test/e2e/scenario/plugins/nextjsPlugin.scenario.ts @@ -1,7 +1,8 @@ import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' import { runBasePluginErrorTests } from './basePluginErrorTests' -import { runBasePluginRouterTests } from './basePluginRouterTests' +import { createBasePluginRouterConfig, runBasePluginRouterTests } from './basePluginRouterTests' +import { clickAndWaitForURL, goHome } from './navigationUtils' const nextjsVariants = [ { @@ -25,12 +26,13 @@ runBasePluginRouterTests( name, loadApp: (b: ReturnType) => b.withNextjsApp(routerType), viewPrefix, - router: { + router: createBasePluginRouterConfig({ homeViewName: viewPrefix || '/', homeUrlPattern, userRouteName: '/user/[id]', guidesRouteName: '/guides/[...slug]', - }, + viewPrefix, + }), })) ) @@ -43,6 +45,7 @@ runBasePluginErrorTests( clientErrorMessage, expectedFramework: 'nextjs', expectsBrowserConsoleErrors: true, + errorHandledSelector: '[data-testid="error-handled"][data-error-reported]', }, })) ) @@ -55,12 +58,20 @@ test.describe('plugin: nextjs', () => { await page.waitForSelector('[data-testid="sidebar"]') expect(await page.textContent('[data-testid="sidebar"]')).toContain('Sidebar: Home') - await page.click('text=Go to User 42') - await page.waitForURL('**/user/42?admin=true') + await clickAndWaitForURL( + page, + '[data-testid="go-to-user"]', + '**/user/42?admin=true', + '[data-testid="change-query-params"]' + ) expect(await page.textContent('[data-testid="sidebar"]')).toContain('Sidebar: User 42') - await page.click('text=Back to Home') + await goHome(page, { + clickSelector: '[data-testid="back-to-home"]', + urlPattern: '**/', + readySelector: '[data-testid="go-to-user"]', + }) await flushEvents() @@ -79,8 +90,12 @@ test.describe('plugin: nextjs', () => { .withRum() .withNextjsApp('app') .run(async ({ page, flushEvents, intakeRegistry, withBrowserLogs }) => { - await page.click('text=Go to Server Error') - await page.waitForSelector('[data-testid="error-handled"]') + await clickAndWaitForURL( + page, + '[data-testid="go-to-server-error"]', + '**/error-test/server-error?throw=true', + '[data-testid="error-handled"][data-error-reported]' + ) await flushEvents() @@ -101,8 +116,12 @@ test.describe('plugin: nextjs', () => { .withRum() .withNextjsApp('app') .run(async ({ page, flushEvents, intakeRegistry, withBrowserLogs }) => { - await page.click('text=Go to Global Error') - await page.waitForSelector('[data-testid="global-error-boundary"]') + await clickAndWaitForURL( + page, + '[data-testid="go-to-global-error"]', + '**/global-error-test?throw=true', + '[data-testid="global-error-boundary"]' + ) await flushEvents() diff --git a/test/e2e/scenario/plugins/nuxtPlugin.scenario.ts b/test/e2e/scenario/plugins/nuxtPlugin.scenario.ts index 2fd026a900..30201b65c6 100644 --- a/test/e2e/scenario/plugins/nuxtPlugin.scenario.ts +++ b/test/e2e/scenario/plugins/nuxtPlugin.scenario.ts @@ -1,6 +1,6 @@ import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' -import { runBasePluginRouterTests } from './basePluginRouterTests' +import { createBasePluginRouterConfig, runBasePluginRouterTests } from './basePluginRouterTests' const nuxtBasePluginConfig = { name: 'nuxt', @@ -11,12 +11,13 @@ const nuxtBasePluginConfig = { runBasePluginRouterTests([ { ...nuxtBasePluginConfig, - router: { + router: createBasePluginRouterConfig({ homeViewName: '/', homeUrlPattern: '**/', userRouteName: '/user/[id]', guidesRouteName: '/guides/[...slug]', - }, + viewPrefix: '', + }), }, ]) @@ -25,10 +26,10 @@ test.describe('plugin: nuxt router', () => { .withRum() .withNuxtApp() .run(async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to User 42') + await page.click('[data-testid="go-to-user"]') await page.waitForURL('**/user/42?admin=true') - await page.click('text=Go to Section') + await page.click('[data-testid="go-to-section"]') await page.waitForURL('**/user/42#section') await flushEvents() diff --git a/test/e2e/scenario/plugins/reactPlugin.scenario.ts b/test/e2e/scenario/plugins/reactPlugin.scenario.ts index fcafe3aeea..790c44bc8d 100644 --- a/test/e2e/scenario/plugins/reactPlugin.scenario.ts +++ b/test/e2e/scenario/plugins/reactPlugin.scenario.ts @@ -1,7 +1,8 @@ import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' import { runBasePluginErrorTests } from './basePluginErrorTests' -import { runBasePluginRouterTests } from './basePluginRouterTests' +import { createBasePluginRouterConfig, runBasePluginRouterTests } from './basePluginRouterTests' +import { clickAndWait, clickAndWaitForURL } from './navigationUtils' const reactApps = [ { appName: 'react-router-v6-app', description: 'React Router v6' }, @@ -19,12 +20,13 @@ runBasePluginRouterTests( name, loadApp, viewPrefix, - router: { + router: createBasePluginRouterConfig({ homeViewName: '/', homeUrlPattern: '**/', userRouteName: '/user/:id', guidesRouteName: '/guides/:slug', - }, + viewPrefix, + }), })) ) @@ -49,7 +51,7 @@ test.describe('plugin: react', () => { .withRum() .withApp(appName) .run(async ({ flushEvents, intakeRegistry, page }) => { - await page.click('text=Go to Tracked') + await page.click('[data-testid="go-to-tracked"]') await flushEvents() const vitalEvents = intakeRegistry.rumVitalEvents[0] @@ -61,8 +63,12 @@ test.describe('plugin: react', () => { .withRum() .withApp(appName) .run(async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to Wildcard') - await page.waitForURL('**/wildcard/foo/bar') + await clickAndWaitForURL( + page, + '[data-testid="go-to-wildcard"]', + '**/wildcard/foo/bar', + '[data-testid="back-to-home"]' + ) await flushEvents() @@ -75,10 +81,13 @@ test.describe('plugin: react', () => { .withRum() .withApp(appName) .run(async ({ page, flushEvents, intakeRegistry, withBrowserLogs }) => { - await page.click('text=Go to Error Test') - await page.waitForURL('**/error-test') - await page.click('[data-testid="trigger-error"]') - await page.waitForSelector('[data-testid="error-handled"]') + await clickAndWaitForURL( + page, + '[data-testid="go-to-error-test"]', + '**/error-test', + '[data-testid="trigger-error"]' + ) + await clickAndWait(page, '[data-testid="trigger-error"]', { readySelector: '[data-testid="error-handled"]' }) await flushEvents() diff --git a/test/e2e/scenario/plugins/vuePlugin.scenario.ts b/test/e2e/scenario/plugins/vuePlugin.scenario.ts index b2ce0aec7e..11e1e66388 100644 --- a/test/e2e/scenario/plugins/vuePlugin.scenario.ts +++ b/test/e2e/scenario/plugins/vuePlugin.scenario.ts @@ -1,7 +1,8 @@ import { test, expect } from '@playwright/test' import { createTest } from '../../lib/framework' import { runBasePluginErrorTests } from './basePluginErrorTests' -import { runBasePluginRouterTests } from './basePluginRouterTests' +import { createBasePluginRouterConfig, runBasePluginRouterTests } from './basePluginRouterTests' +import { clickAndWait, clickAndWaitForURL } from './navigationUtils' const vueBasePluginConfig = { name: 'vue', @@ -12,12 +13,13 @@ const vueBasePluginConfig = { runBasePluginRouterTests([ { ...vueBasePluginConfig, - router: { + router: createBasePluginRouterConfig({ homeViewName: '/', homeUrlPattern: '**/', userRouteName: '/user/:id', guidesRouteName: '/guides/:catchAll(.*)*', - }, + viewPrefix: '', + }), }, ]) @@ -37,8 +39,13 @@ test.describe('plugin: vue', () => { .withRum() .withVueApp() .run(async ({ page, flushEvents, intakeRegistry }) => { - await page.click('text=Go to Error Test') - await page.click('[data-testid="trigger-error"]') + await clickAndWaitForURL( + page, + '[data-testid="go-to-error-test"]', + '**/error-test', + '[data-testid="trigger-error"]' + ) + await clickAndWait(page, '[data-testid="trigger-error"]', { readySelector: '[data-testid="error-handled"]' }) await flushEvents()