chore: import upstream snapshot with attribution
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
CD - Docker - GHCR Images / Build and Push Images (push) Has been cancelled
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
CD - Docker - GHCR Images / Build and Push Images (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { BrowserContext } from '@playwright/test';
|
||||
|
||||
export async function addGrowthbookCookie({
|
||||
context,
|
||||
variation
|
||||
}: {
|
||||
context: BrowserContext;
|
||||
variation: string;
|
||||
}) {
|
||||
await context.addCookies([
|
||||
{
|
||||
name: 'gbuuid',
|
||||
value: variation,
|
||||
// Weirdly, it seems necessary to prefix the domain with a dot. This seems
|
||||
// to be a peculiarity of Playwright.
|
||||
domain: process.env.COOKIE_DOMAIN || 'localhost',
|
||||
path: '/',
|
||||
expires: Math.floor(Date.now() / 1000) + 400 * 24 * 60 * 60 // 400 days from now
|
||||
}
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { expect, type Page } from '@playwright/test';
|
||||
|
||||
export const alertToBeVisible = async (page: Page, text: string) =>
|
||||
await expect(page.getByRole('alert').filter({ hasText: text })).toBeVisible();
|
||||
@@ -0,0 +1,41 @@
|
||||
import { type Page } from '@playwright/test';
|
||||
|
||||
export const getEditors = (page: Page) => {
|
||||
return page.getByRole('textbox', { name: /editor content/i });
|
||||
};
|
||||
|
||||
export const focusEditor = async ({
|
||||
page,
|
||||
isMobile
|
||||
}: {
|
||||
page: Page;
|
||||
isMobile: boolean;
|
||||
}) => {
|
||||
if (isMobile) {
|
||||
const codeBtn = page.getByRole('tab', { name: 'Code' });
|
||||
// The outer div intercepts the click action of its children,
|
||||
// preventing Playwright from verifying if the children actually receive the click.
|
||||
// In reality, the children do receive the click, so we bypass that check here.
|
||||
await codeBtn.click({ force: true });
|
||||
}
|
||||
|
||||
await getEditors(page).focus();
|
||||
};
|
||||
|
||||
export async function clearEditor({
|
||||
page,
|
||||
browserName,
|
||||
isMobile = false
|
||||
}: {
|
||||
page: Page;
|
||||
browserName: string;
|
||||
isMobile?: boolean;
|
||||
}) {
|
||||
// TODO: replace with ControlOrMeta when it's supported
|
||||
if (browserName === 'webkit' && !isMobile) {
|
||||
await page.keyboard.press('Meta+a');
|
||||
} else {
|
||||
await page.keyboard.press('Control+a');
|
||||
}
|
||||
await page.keyboard.press('Backspace');
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
type Email = {
|
||||
Subject: string;
|
||||
ID: string;
|
||||
From: { Address: string; Name: string };
|
||||
To: Array<{ Address: string; Name: string }>;
|
||||
};
|
||||
|
||||
type AllEmails = {
|
||||
messages: Email[];
|
||||
total: number;
|
||||
count: number;
|
||||
};
|
||||
|
||||
const host = process.env.MAILPIT_HOST || 'localhost';
|
||||
|
||||
export const getAllEmails = async (): Promise<AllEmails> => {
|
||||
const res = await fetch(`http://${host}:8025/api/v1/messages`);
|
||||
return res.json() as Promise<AllEmails>;
|
||||
};
|
||||
|
||||
export const getFirstEmail = (allEmails: { messages: Email[] }) => {
|
||||
return allEmails.messages[0];
|
||||
};
|
||||
|
||||
export const getSubject = (email: { Subject: string }) => {
|
||||
return email.Subject;
|
||||
};
|
||||
|
||||
export const deleteAllEmails = async () => {
|
||||
await fetch(`http://${host}:8025/api/v1/messages`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Page } from '@playwright/test';
|
||||
|
||||
export async function signout(page: Page) {
|
||||
await page.context().clearCookies({ name: 'jwt_access_token' });
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { APIRequestContext, expect } from '@playwright/test';
|
||||
|
||||
const ensureLeadingSlash = (endpoint: string) =>
|
||||
endpoint[0] === '/' ? endpoint : '/' + endpoint;
|
||||
|
||||
export const authedRequest = async ({
|
||||
request,
|
||||
method,
|
||||
endpoint,
|
||||
data
|
||||
}: {
|
||||
request: APIRequestContext;
|
||||
method: 'post' | 'put';
|
||||
endpoint: string;
|
||||
data: Record<string, unknown>;
|
||||
}) => {
|
||||
const csrfToken = (await request.storageState()).cookies.find(
|
||||
c => c.name === 'csrf_token'
|
||||
)?.value;
|
||||
|
||||
expect(csrfToken).toBeTruthy();
|
||||
|
||||
const res = await request[method](
|
||||
process.env.API_LOCATION + ensureLeadingSlash(endpoint),
|
||||
{
|
||||
data,
|
||||
headers: { 'csrf-token': csrfToken! }
|
||||
}
|
||||
);
|
||||
expect(res.status()).toBe(200);
|
||||
return res;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export const allowTrailingSlash = (url: string) => RegExp(url + '[/]?$');
|
||||
@@ -0,0 +1 @@
|
||||
export const isMacOS = process.platform === 'darwin';
|
||||
Reference in New Issue
Block a user