This commit is contained in:
zhanggy committed 2025-11-05 14:46:49 +08:00
1 parent fc250c54ed
commit 5eec516459
62 files changed
+3912 -3376

No files matched your search

+39 -38
View File
@@ -1,17 +1,18 @@
import * as base from '@playwright/test'
import { _electron as electron, Page, ElectronApplication } from 'playwright'
import { join } from 'path'
import { main } from '../package.json'
import TestUtil from './testUtil.mjs'
import type { ElectronApplication, Page } from 'playwright';
import { join } from 'node:path';
import * as base from '@playwright/test';
import { _electron as electron } from 'playwright';
import { main } from '../package.json';
import TestUtil from './testUtil.mjs';
let appElectron: ElectronApplication
let page: Page
let appElectron: ElectronApplication;
let page: Page;
const __cwd = process.cwd()
const __isCiProcess = process.env.CI === 'true'
const __testPath = join(__cwd, 'tests')
const __testResultPath = join(__testPath, 'results')
const __testScreenshotPath = join(__testResultPath, 'screenshots')
const __cwd = process.cwd();
const __isCiProcess = process.env.CI === 'true';
const __testPath = join(__cwd, 'tests');
const __testResultPath = join(__testPath, 'results');
const __testScreenshotPath = join(__testResultPath, 'screenshots');
export const beforeAll = async () => {
// Open Electron app from build directory
@@ -23,60 +24,60 @@ export const beforeAll = async () => {
'--ignore-certificate-errors',
'--ignore-ssl-errors',
'--ignore-blocklist',
'--ignore-gpu-blocklist'
'--ignore-gpu-blocklist',
],
locale: 'en-US',
colorScheme: 'light',
env: {
...process.env,
NODE_ENV: 'production'
}
})
page = await appElectron.firstWindow()
NODE_ENV: 'production',
},
});
page = await appElectron.firstWindow();
await page.waitForEvent('load')
await page.waitForEvent('load');
page.on('console', console.log)
page.on('pageerror', console.log)
page.on('console', console.log);
page.on('pageerror', console.log);
const evaluateResult = await appElectron.evaluate(
async ({ app, BrowserWindow }) => {
const currentWindow = BrowserWindow.getFocusedWindow()
const currentWindow = BrowserWindow.getFocusedWindow();
// Fix window position for testing
currentWindow.setPosition(50, 50)
currentWindow.setSize(1080, 560)
currentWindow.setPosition(50, 50);
currentWindow.setSize(1080, 560);
return {
packaged: app.isPackaged,
dataPath: app.getPath('userData')
}
}
)
dataPath: app.getPath('userData'),
};
},
);
base.expect(evaluateResult.packaged, 'app is not packaged').toBe(false)
}
base.expect(evaluateResult.packaged, 'app is not packaged').toBe(false);
};
export const afterAll = async () => {
await appElectron.close()
}
await appElectron.close();
};
export const test = base.test.extend({
// eslint-disable-next-line no-empty-pattern
page: async ({}, use) => {
await use(page)
await use(page);
},
// @ts-expect-error: `util` is not using types in playwright
util: async ({ page }, use, testInfo) => {
await use(new TestUtil(page, testInfo, __testScreenshotPath))
}
})
await use(new TestUtil(page, testInfo, __testScreenshotPath));
},
});
export const expect = base.expect
export const expect = base.expect;
export default {
test,
expect,
beforeAll,
afterAll
}
afterAll,
};
+15 -15
View File
@@ -1,38 +1,38 @@
import { test, expect, beforeAll, afterAll } from '../fixtures.mjs'
import { afterAll, beforeAll, expect, test } from '../fixtures.mjs';
test.beforeAll(beforeAll)
test.afterAll(afterAll)
test.beforeAll(beforeAll);
test.afterAll(afterAll);
// @ts-expect-error: `util` is not using types in playwright
test('Document element check', async ({ page, util }) => {
try {
await expect(
page.getByTestId('main-logo').first(),
`Confirm main logo is visible`
).toBeVisible()
`Confirm main logo is visible`,
).toBeVisible();
await expect(
page.getByTestId('select-language').first(),
`Confirm language selector is visible`
).toBeVisible()
`Confirm language selector is visible`,
).toBeVisible();
await util.captureScreenshot(page, 'result')
await util.captureScreenshot(page, 'result');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
// @ts-expect-error: `util` is not using types in playwright
test('Counter button click check', async ({ page, util }) => {
try {
await page.getByTestId('btn-counter').click({ clickCount: 10, delay: 50 })
await page.getByTestId('btn-counter').click({ clickCount: 10, delay: 50 });
const counterValueElement = await page
.getByTestId('counter-badge')
.getByRole('status')
.innerHTML()
.innerHTML();
expect(counterValueElement).toBe('10')
expect(counterValueElement).toBe('10');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
+68 -68
View File
@@ -1,174 +1,174 @@
import { test, expect, beforeAll, afterAll } from '../fixtures.mjs'
import { afterAll, beforeAll, expect, test } from '../fixtures.mjs';
test.beforeAll(beforeAll)
test.afterAll(afterAll)
test.beforeAll(beforeAll);
test.afterAll(afterAll);
// @ts-expect-error: `util` is not using types in playwright
test('Template list page navigation and basic functionality', async ({
page,
util
util,
}) => {
try {
// Navigate to templates page
await page.goto('/')
await page.waitForURL('**/#/templates')
await page.goto('/');
await page.waitForURL('**/#/templates');
// Check if we're on the templates page
await expect(page.getByText('模板列表')).toBeVisible()
await expect(page.getByText('模板列表')).toBeVisible();
// Check if "No templates" message is visible initially
await expect(page.getByText('暂无模板,请先创建模板。')).toBeVisible()
await expect(page.getByText('暂无模板,请先创建模板。')).toBeVisible();
// Check if "Create Template" button is visible
await expect(page.getByText('创建模板')).toBeVisible()
await expect(page.getByText('创建模板')).toBeVisible();
await util.captureScreenshot(page, 'template-list-no-templates')
await util.captureScreenshot(page, 'template-list-no-templates');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
// @ts-expect-error: `util` is not using types in playwright
test('Create template page navigation and functionality', async ({
page,
util
util,
}) => {
try {
// Navigate to templates page
await page.goto('/')
await page.waitForURL('**/#/templates')
await page.goto('/');
await page.waitForURL('**/#/templates');
// Click create template button
await page.getByText('创建模板').click()
await page.waitForURL('**/#/create-template')
await page.getByText('创建模板').click();
await page.waitForURL('**/#/create-template');
// Check if we're on the create template page
await expect(page.getByText('创建模板')).toBeVisible()
await expect(page.getByText('创建模板')).toBeVisible();
// Check if form elements are visible
await expect(page.getByLabel('模板名称 *')).toBeVisible()
await expect(page.getByLabel('模板描述')).toBeVisible()
await expect(page.getByLabel('模板名称 *')).toBeVisible();
await expect(page.getByLabel('模板描述')).toBeVisible();
await util.captureScreenshot(page, 'create-template-page')
await util.captureScreenshot(page, 'create-template-page');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
// @ts-expect-error: `util` is not using types in playwright
test('Add files and directories to template', async ({ page, util }) => {
try {
// Navigate to create template page
await page.goto('/#/create-template')
await page.goto('/#/create-template');
// Fill in template name and description
await page.getByLabel('模板名称 *').fill('Test Template')
await page.getByLabel('模板描述').fill('This is a test template')
await page.getByLabel('模板名称 *').fill('Test Template');
await page.getByLabel('模板描述').fill('This is a test template');
// Add a file
await page.getByText('添加文件').click()
await page.getByText('添加文件').click();
// Wait for dialog to appear and fill in file details
await page
.locator('[data-testid="add-file-path-input"]')
.fill('src/index.js')
.fill('src/index.js');
await page
.locator('[data-testid="add-file-content-input"]')
.fill('console.log("Hello World");')
await page.getByText('添加').click()
.fill('console.log("Hello World");');
await page.getByText('添加').click();
// Add a directory
await page.getByText('添加目录').click()
await page.getByText('添加目录').click();
// Wait for dialog to appear and fill in directory details
await page
.locator('[data-testid="add-dir-path-input"]')
.fill('src/components')
await page.getByText('添加').click()
.fill('src/components');
await page.getByText('添加').click();
// Verify items were added to the tables
await expect(page.getByText('src/index.js')).toBeVisible()
await expect(page.getByText('src/components')).toBeVisible()
await expect(page.getByText('src/index.js')).toBeVisible();
await expect(page.getByText('src/components')).toBeVisible();
await util.captureScreenshot(page, 'template-with-content')
await util.captureScreenshot(page, 'template-with-content');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
// @ts-expect-error: `util` is not using types in playwright
test('Template creation and listing', async ({ page, util }) => {
try {
// Navigate to create template page
await page.goto('/#/create-template')
await page.goto('/#/create-template');
// Fill in template name and description
await page.getByLabel('模板名称 *').fill('Test Template')
await page.getByLabel('模板描述').fill('This is a test template')
await page.getByLabel('模板名称 *').fill('Test Template');
await page.getByLabel('模板描述').fill('This is a test template');
// Add a file
await page.getByText('添加文件').click()
await page.getByText('添加文件').click();
await page
.locator('[data-testid="add-file-path-input"]')
.fill('src/index.js')
.fill('src/index.js');
await page
.locator('[data-testid="add-file-content-input"]')
.fill('console.log("Hello World");')
await page.getByText('添加').click()
.fill('console.log("Hello World");');
await page.getByText('添加').click();
// Save template
await page.getByText('保存模板').click()
await page.getByText('保存模板').click();
// Wait for redirect to templates page
await page.waitForURL('**/#/templates')
await page.waitForURL('**/#/templates');
// Check if the created template is listed
await expect(page.getByText('Test Template')).toBeVisible()
await expect(page.getByText('This is a test template')).toBeVisible()
await expect(page.getByText('Test Template')).toBeVisible();
await expect(page.getByText('This is a test template')).toBeVisible();
await util.captureScreenshot(page, 'template-list-with-template')
await util.captureScreenshot(page, 'template-list-with-template');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
// @ts-expect-error: `util` is not using types in playwright
test('View template details', async ({ page, util }) => {
try {
// Navigate to templates page
await page.goto('/#/templates')
await page.goto('/#/templates');
// Wait for template to appear and click view button
// First we need to create a template for this test
if (await page.getByText('暂无模板,请先创建模板。').isVisible()) {
await page.getByText('创建模板').click()
await page.getByText('创建模板').click();
// Create a test template
await page.getByLabel('模板名称 *').fill('View Test Template')
await page.getByLabel('模板描述').fill('Template for view test')
await page.getByLabel('模板名称 *').fill('View Test Template');
await page.getByLabel('模板描述').fill('Template for view test');
await page.getByText('添加文件').click()
await page.getByText('添加文件').click();
await page
.locator('[data-testid="add-file-path-input"]')
.fill('src/test.js')
.fill('src/test.js');
await page
.locator('[data-testid="add-file-content-input"]')
.fill('console.log("Test");')
await page.getByText('添加').click()
.fill('console.log("Test");');
await page.getByText('添加').click();
await page.getByText('保存模板').click()
await page.waitForURL('**/#/templates')
await page.getByText('保存模板').click();
await page.waitForURL('**/#/templates');
}
// Wait for template to appear and click view button
await page.getByRole('button', { name: '查看' }).click()
await page.getByRole('button', { name: '查看' }).click();
// Check if template detail dialog appears
await expect(page.getByText('模板详情')).toBeVisible()
await expect(page.getByText('src/test.js')).toBeVisible()
await expect(page.getByText('模板详情')).toBeVisible();
await expect(page.getByText('src/test.js')).toBeVisible();
await util.captureScreenshot(page, 'template-detail-view')
await util.captureScreenshot(page, 'template-detail-view');
} catch (error) {
throw await util.onTestError(error)
throw await util.onTestError(error);
}
})
});
+16 -16
View File
@@ -1,40 +1,40 @@
import { Page } from 'playwright'
import { TestInfo } from 'playwright/test'
import type { Page } from 'playwright';
import type { TestInfo } from 'playwright/test';
export default class TestUtil {
_page: Page
_page: Page;
_testInfo: TestInfo
_testInfo: TestInfo;
_testScreenshotPath: string
_testScreenshotPath: string;
constructor(page: Page, testInfo: TestInfo, testScreenshotPath: string) {
this._page = page
this._testInfo = testInfo
this._testScreenshotPath = testScreenshotPath
this._page = page;
this._testInfo = testInfo;
this._testScreenshotPath = testScreenshotPath;
}
async captureScreenshot(pageInstance: Page, screenshotName: string) {
if (!pageInstance) {
return
return;
}
try {
const screenshotPath = `${this._testScreenshotPath}/${screenshotName || `unknown_${Date.now()}`}.png`
const screenshotPath = `${this._testScreenshotPath}/${screenshotName || `unknown_${Date.now()}`}.png`;
await pageInstance.screenshot({ path: screenshotPath })
await pageInstance.screenshot({ path: screenshotPath });
} catch {
// Do nothing
}
}
async onTestError(error: Error) {
const titleLists = [...this._testInfo.titlePath]
titleLists.shift()
const title = titleLists.join('-')
const titleLists = [...this._testInfo.titlePath];
titleLists.shift();
const title = titleLists.join('-');
await this.captureScreenshot(this._page, `${title}_${Date.now()}`)
await this.captureScreenshot(this._page, `${title}_${Date.now()}`);
return new Error(error.message)
return new Error(error.message);
}
}