mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
fix(test): e2e stability (#14749)
#### PR Dependency Tree * **PR #14749** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved link preview reliability by updating request identification to better match modern browsers. * **Tests** * Made end-to-end and integration tests deterministic and more robust, improving AI chat, image generation, attachment handling, settings visibility, and editor flows. * **Chores** * Updated underlying tooling versions to enhance stability and compatibility. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -53,34 +53,34 @@ test.describe('AIChatWith/Attachments', () => {
|
||||
loggedInPage: page,
|
||||
utils,
|
||||
}) => {
|
||||
const randomStr1 = Math.random().toString(36).substring(2, 6);
|
||||
const randomStr2 = Math.random().toString(36).substring(2, 6);
|
||||
const textContent1 = `Attachment${randomStr1} is a cute cat`;
|
||||
const textContent2 = `Attachment${randomStr2} is a cute dog`;
|
||||
const textContent1 = 'This attachment describes a cute cat.';
|
||||
const textContent2 = 'This attachment describes a cute dog.';
|
||||
const buffer1 = Buffer.from(textContent1);
|
||||
const buffer2 = Buffer.from(textContent2);
|
||||
const firstName = 'cat-document.txt';
|
||||
const secondName = 'dog-document.txt';
|
||||
|
||||
await utils.chatPanel.chatWithAttachments(
|
||||
page,
|
||||
[
|
||||
{
|
||||
name: 'document1.txt',
|
||||
name: firstName,
|
||||
mimeType: 'text/plain',
|
||||
buffer: buffer1,
|
||||
},
|
||||
{
|
||||
name: 'document2.txt',
|
||||
name: secondName,
|
||||
mimeType: 'text/plain',
|
||||
buffer: buffer2,
|
||||
},
|
||||
],
|
||||
`Which animal is Attachment${randomStr1} and which animal is Attachment${randomStr2}? Answer with both attachment names.`
|
||||
`Which animal is described in ${firstName} and which animal is described in ${secondName}? Answer with both attachment names.`
|
||||
);
|
||||
|
||||
await utils.chatPanel.waitForHistory(page, [
|
||||
{
|
||||
role: 'user',
|
||||
content: `Which animal is Attachment${randomStr1} and which animal is Attachment${randomStr2}? Answer with both attachment names.`,
|
||||
content: `Which animal is described in ${firstName} and which animal is described in ${secondName}? Answer with both attachment names.`,
|
||||
},
|
||||
{
|
||||
role: 'assistant',
|
||||
@@ -90,8 +90,8 @@ test.describe('AIChatWith/Attachments', () => {
|
||||
|
||||
await expect(async () => {
|
||||
const { content } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
expect(content).toMatch(new RegExp(`Attachment${randomStr1}`));
|
||||
expect(content).toMatch(new RegExp(`Attachment${randomStr2}`));
|
||||
expect(content).toContain(firstName);
|
||||
expect(content).toContain(secondName);
|
||||
expect(content).toMatch(/cat/i);
|
||||
expect(content).toMatch(/dog/i);
|
||||
}).toPass({ timeout: 20000 });
|
||||
|
||||
@@ -37,11 +37,11 @@ test.describe('AIChatWith/Image', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
const { content } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
await expect(
|
||||
content.toLowerCase().includes('kitten') ||
|
||||
content.toLowerCase().includes('cat')
|
||||
).toBe(true);
|
||||
await expect(async () => {
|
||||
const { content } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
expect(content.length).toBeGreaterThan(20);
|
||||
expect(content).toMatch(/cat|kitten|feline|tabby|fluffy/i);
|
||||
}).toPass({ timeout: 20000 });
|
||||
});
|
||||
|
||||
test('support chat with mutiple images', async ({
|
||||
|
||||
@@ -28,11 +28,10 @@ test.describe('AIInsertion/SaveAsBlock', () => {
|
||||
|
||||
const { actions } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
await actions.saveAsBlock();
|
||||
await page.getByText('Successfully saved chat to a block').waitFor();
|
||||
|
||||
// Switch to edgeless mode
|
||||
await utils.editor.isEdgelessMode(page);
|
||||
|
||||
// Verify the ai block is created
|
||||
await page.waitForSelector('affine-edgeless-ai-chat');
|
||||
const aiBlock = await page.locator('affine-edgeless-ai-chat');
|
||||
await expect(aiBlock).toBeVisible();
|
||||
|
||||
@@ -513,9 +513,9 @@ test.describe('AISettings/Embedding', () => {
|
||||
await utils.settings.openSettingsPanel(page);
|
||||
await page.context().setOffline(true);
|
||||
await utils.settings.ignoreDocForEmbedding(page, 'Test Doc', false);
|
||||
await expect(
|
||||
page.getByText(/Failed to update ignored docs/i)
|
||||
).toBeVisible();
|
||||
await page
|
||||
.getByText(/Failed to update ignored docs/i)
|
||||
.waitFor({ state: 'visible', timeout: 20000 });
|
||||
await page.context().setOffline(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -575,7 +575,14 @@ export class EditorUtils {
|
||||
),
|
||||
generateImage: this.createAction(page, async () => {
|
||||
await page.getByTestId('action-generate-image').click();
|
||||
await page.keyboard.type('generate an image');
|
||||
const input = page.locator(
|
||||
'affine-ai-panel-widget .ai-panel-container textarea'
|
||||
);
|
||||
await input.waitFor({ state: 'visible' });
|
||||
await input.fill('generate an image');
|
||||
await page.getByTestId('ai-panel-input-send').waitFor({
|
||||
state: 'visible',
|
||||
});
|
||||
await page.getByTestId('ai-panel-input-send').click();
|
||||
}),
|
||||
generateCaption: this.createAction(page, () =>
|
||||
|
||||
@@ -6,6 +6,9 @@ const WORKSPACE_EMBEDDING_SWITCH_TEST_ID = 'workspace-embedding-setting-switch';
|
||||
export class SettingsPanelUtils {
|
||||
public static async openSettingsPanel(page: Page) {
|
||||
if (await page.getByTestId('workspace-setting:embedding').isHidden()) {
|
||||
await page
|
||||
.getByTestId('slider-bar-workspace-setting-button')
|
||||
.waitFor({ state: 'visible' });
|
||||
await page.getByTestId('slider-bar-workspace-setting-button').click();
|
||||
await page.getByTestId('workspace-setting:embedding').click();
|
||||
await page.getByTestId('workspace-embedding-setting-header').waitFor({
|
||||
@@ -18,7 +21,7 @@ export class SettingsPanelUtils {
|
||||
if (
|
||||
await page.getByTestId('workspace-embedding-setting-wrapper').isVisible()
|
||||
) {
|
||||
await page.getByTestId('modal-close-button').click();
|
||||
await page.keyboard.press('Escape');
|
||||
await page.getByTestId('workspace-embedding-setting-wrapper').waitFor({
|
||||
state: 'hidden',
|
||||
});
|
||||
@@ -161,13 +164,22 @@ export class SettingsPanelUtils {
|
||||
const searcher = await page.getByTestId('doc-selector-layout');
|
||||
const searchInput = await page.getByTestId('doc-selector-search-input');
|
||||
|
||||
await searchInput.waitFor({ state: 'visible' });
|
||||
await searchInput.focus();
|
||||
await page.keyboard.insertText(doc);
|
||||
|
||||
const pageListItem = searcher.getByTestId('doc-list-item');
|
||||
await expect(pageListItem).toHaveCount(1);
|
||||
const pageListItemTitle = pageListItem.getByTestId('doc-list-item-title');
|
||||
await expect(pageListItemTitle).toHaveText(doc);
|
||||
const pageListItem = searcher
|
||||
.getByTestId('doc-list-item')
|
||||
.filter({
|
||||
has: page
|
||||
.getByTestId('doc-list-item-title')
|
||||
.getByText(doc, { exact: true }),
|
||||
})
|
||||
.first();
|
||||
await expect(pageListItem).toBeVisible();
|
||||
await expect(pageListItem.getByTestId('doc-list-item-title')).toHaveText(
|
||||
doc
|
||||
);
|
||||
await pageListItem.click();
|
||||
|
||||
await searcher.getByTestId('doc-selector-confirm-button').click();
|
||||
@@ -200,7 +212,7 @@ export class SettingsPanelUtils {
|
||||
await searchInput.focus();
|
||||
await page.keyboard.insertText(doc);
|
||||
|
||||
const pageListItem = searcher.getByTestId('page-list-item');
|
||||
const pageListItem = searcher.getByTestId('doc-list-item');
|
||||
await expect(pageListItem).toHaveCount(1);
|
||||
|
||||
await pageListItem.getByTestId('affine-checkbox').uncheck();
|
||||
|
||||
@@ -37,9 +37,12 @@ export async function waitForAllPagesLoad(page: Page) {
|
||||
}
|
||||
|
||||
export async function clickNewPageButton(page: Page, title?: string) {
|
||||
await page.getByTestId('sidebar-new-page-button').click({
|
||||
// default timeout is 5000ms, but it's not enough for the CI first page load
|
||||
timeout: 20000,
|
||||
const newPageButton = page.getByTestId('sidebar-new-page-button');
|
||||
await expect(newPageButton).toBeVisible({
|
||||
timeout: 30000,
|
||||
});
|
||||
await newPageButton.click({
|
||||
timeout: 30000,
|
||||
});
|
||||
await waitForEmptyEditor(page);
|
||||
if (title) {
|
||||
|
||||
Reference in New Issue
Block a user