-
Notifications
You must be signed in to change notification settings - Fork 190
✅ [RUM-17233] Add Shopify checkout views and actions e2e test #4941
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d160743
fd9496c
7c81df8
ef6cdb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import type { Page } from '@playwright/test' | ||
| import { getShopifyStorePassword } from '../../../../scripts/lib/secrets.ts' | ||
|
|
||
| // A Datadog-owned dev store, password-protected, used only to exercise browser-rum-shopify | ||
| // against a real storefront + checkout + Custom Pixel sandbox. | ||
| const SHOPIFY_STORE_URL = 'https://custom-pixel-e2e.myshopify.com/' | ||
|
|
||
| export function buildShopifyUrl(): string { | ||
| return SHOPIFY_STORE_URL | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe since it's a constant we don't need this? |
||
|
|
||
| // Dev stores gate every page behind a storefront password until unlocked for the session. | ||
| const PASSWORD_PATH = /\/password\/?$/ | ||
|
|
||
| export async function unlockShopifyStorePassword(page: Page): Promise<void> { | ||
| if (!PASSWORD_PATH.test(new URL(page.url()).pathname)) { | ||
| return | ||
| } | ||
|
|
||
| await page.getByRole('textbox', { name: /password/i }).fill(getShopifyStorePassword()) | ||
| await page.getByRole('button', { name: /enter/i }).click() | ||
| await page.waitForURL((url) => !PASSWORD_PATH.test(url.pathname)) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ export interface SetupOptions { | |
| callerLocation?: CallerLocation | ||
| mockClock: boolean | ||
| salesforceApp: SalesforceApp | undefined | ||
| shopifyApp: boolean | ||
| } | ||
|
|
||
| export interface CallerLocation { | ||
|
|
@@ -343,6 +344,41 @@ export async function salesforceSetup(options: SetupOptions, servers: Servers, p | |
| return '' | ||
| } | ||
|
|
||
| // Matches the CDN URL used by the store's Theme Liquid snippet and Custom Pixel for the main | ||
| // bundle and its dynamically-imported chunks (e.g. the session replay recorder), served from | ||
| // `https://www.datadoghq-browser-agent.com/<site>/v<major>/[chunks/]<name->]datadog-rum-shopify.js` | ||
| const SHOPIFY_ASSET_URL_PATTERN = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay not related specifically to your PR but how about making a function to reuse with Salesforce? Since it's the same pattern except for |
||
| /datadoghq-browser-agent\.com\/[^/]+\/v\d+\/(chunks\/)?([\w-]*datadog-rum-shopify\.js)(?:[?#].*)?$/ | ||
|
|
||
| // Shopify apps don't serve a locally-generated page body; this factory only intercepts the | ||
| // bootstrap script request and injects the RUM configuration read by the store's Theme Liquid | ||
| // snippet and Custom Pixel. | ||
| export async function shopifySetup(options: SetupOptions, servers: Servers, page: Page): Promise<string> { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: those setup functions are templates to render an HTML page the e2e test will load. It seems like you are doing very different things here. What about moving this logic in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was following the example of the Salesforce, which has similar setup pattern
Actually not that different - the part of rendering an HTML page for e2e test is injecting the local sdk version and passing the init options for it - and this is exactly what I'm doing here. This method doesn't render the html - it's rendered by predefined Shopify dev-store - but I still need to override the sdk bundle path and pass the init config for it. Therefore I believe it's the right place to do this, it would look overly cumbersome in |
||
| const shopifyBundleDir = resolve(__dirname, '../../../../packages/browser-rum-shopify/bundle') | ||
|
|
||
| await page.route(SHOPIFY_ASSET_URL_PATTERN, async (route) => { | ||
| const [, chunksSegment, fileName] = SHOPIFY_ASSET_URL_PATTERN.exec(route.request().url()) || [] | ||
| const filePath = resolve(shopifyBundleDir, chunksSegment || '', fileName) | ||
| await route.fulfill({ | ||
| body: await readFile(filePath), | ||
| contentType: 'application/javascript', | ||
| // The snippets load the script with `crossOrigin = 'anonymous'`, so the browser enforces | ||
| // CORS on this response even though it never leaves the machine. | ||
| headers: { 'access-control-allow-origin': '*' }, | ||
| }) | ||
| }) | ||
|
|
||
| if (options.rum) { | ||
| // addInitScript runs on every new document in the page, including the Custom Pixel's | ||
| // sandboxed iframe, so this reaches both the storefront and checkout injection points. | ||
| await page.addInitScript( | ||
| `window.RUM_CONFIGURATION = ${formatConfiguration(options.rum, servers)} | ||
| window.RUM_CONTEXT = ${JSON.stringify(options.context)}` | ||
| ) | ||
| } | ||
| return '' | ||
| } | ||
|
|
||
| function basePage({ header, body, footer }: { header?: string; body?: string; footer?: string }) { | ||
| // prettier-ignore | ||
| // The empty favicon avoids a /favicon.ico request from the browser. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: this file is not just about shopify urls. Maybe rename it to
shopify.tsorshopifyUtils.ts?