多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.8 KiB

import { Locator, Page } from '@playwright/test';
type ResponseSelector = (json: any) => boolean;
export default abstract class BasePage {
readonly rootPage: Page;
abstract get(args?: any): Locator;
constructor(rootPage: Page) {
this.rootPage = rootPage;
}
async verifyToast({ message }: { message: string }) {
await this.rootPage.locator('.ant-message .ant-message-notice-content', { hasText: message }).last().isVisible();
}
async waitForResponse({
// Playwright action that triggers the request i.e locatorSomething.click()
uiAction,
httpMethodsToMatch = [],
requestUrlPathToMatch,
// A function that takes the response body and returns true if the response is the one we are looking for
responseJsonMatcher,
}: {
uiAction: () => Promise<any>;
requestUrlPathToMatch: string;
httpMethodsToMatch?: string[];
responseJsonMatcher?: ResponseSelector;
}) {
// trigger UI action first
await uiAction();
// wait for response
const res = await this.rootPage.waitForResponse(
res =>
res.url().includes(requestUrlPathToMatch) &&
res.status() === 200 &&
httpMethodsToMatch.includes(res.request().method())
);
// handle JSON matcher if provided
let isResJsonMatched = true;
if (responseJsonMatcher) {
try {
isResJsonMatched = responseJsonMatcher(await res.json());
} catch {
isResJsonMatched = false;
}
}
return isResJsonMatched;
}
async attachFile({ filePickUIAction, filePath }: { filePickUIAction: Promise<any>; filePath: string[] }) {
const [fileChooser] = await Promise.all([
// It is important to call waitForEvent before click to set up waiting.
this.rootPage.waitForEvent('filechooser'),
// Opens the file chooser.
filePickUIAction,
]);
await fileChooser.setFiles(filePath);
}
async downloadAndGetFile({ downloadUIAction }: { downloadUIAction: Promise<any> }) {
const [download] = await Promise.all([
// It is important to call waitForEvent before click to set up waiting.
this.rootPage.waitForEvent('download'),
// Triggers the download.
downloadUIAction,
]);
// wait for download to complete
if (await download.failure()) {
throw new Error('Download failed');
}
const file = await download.createReadStream();
const data = await new Promise((resolve, reject) => {
let data = '';
file?.on('data', chunk => (data += chunk));
file?.on('end', () => resolve(data));
file?.on('error', reject);
});
return data as any;
}
async getClipboardText() {
return await this.rootPage.evaluate(() => navigator.clipboard.readText());
}
async os() {
return await this.rootPage.evaluate(() => navigator.platform);
}
async isMacOs() {
return (await this.os()).includes('Mac');
}
}