AFFiNE/tests/affine-desktop/e2e/basic.spec.ts

211 lines
6.6 KiB
TypeScript
Raw Normal View History

import { test } from '@affine-test/kit/electron';
import { withCtrlOrMeta } from '@affine-test/kit/utils/keyboard';
2024-02-21 15:57:18 +03:00
import {
clickNewPageButton,
createLinkedPage,
2024-02-21 15:57:18 +03:00
getBlockSuiteEditorTitle,
waitForEmptyEditor,
2024-02-21 15:57:18 +03:00
} from '@affine-test/kit/utils/page-logic';
import {
clickSideBarCurrentWorkspaceBanner,
clickSideBarSettingButton,
} from '@affine-test/kit/utils/sidebar';
import type { Page } from '@playwright/test';
import { expect } from '@playwright/test';
const historyShortcut = async (page: Page, command: 'goBack' | 'goForward') => {
await withCtrlOrMeta(page, () =>
page.keyboard.press(command === 'goBack' ? '[' : ']', { delay: 50 })
);
};
2023-04-28 09:40:44 +03:00
test('new page', async ({ page, workspace }) => {
await page.getByTestId('sidebar-new-page-button').click({
2023-04-25 02:53:36 +03:00
delay: 100,
});
await page.waitForSelector('v-line');
2023-12-15 10:20:50 +03:00
const flavour = (await workspace.current()).meta.flavour;
2023-04-25 02:53:36 +03:00
expect(flavour).toBe('local');
});
test('app sidebar router forward/back', async ({ page }) => {
{
// create pages
await page.waitForTimeout(500);
2024-02-21 15:57:18 +03:00
await clickNewPageButton(page);
await page.waitForSelector('v-line');
const title = getBlockSuiteEditorTitle(page);
await title.focus();
await title.pressSequentially('test1', {
delay: 100,
});
await page.waitForTimeout(500);
await page.getByTestId('sidebar-new-page-button').click({
delay: 100,
});
await page.waitForSelector('v-line');
await title.focus();
await title.pressSequentially('test2', {
delay: 100,
});
await page.waitForTimeout(500);
await page.getByTestId('sidebar-new-page-button').click({
delay: 100,
});
await page.waitForSelector('v-line');
await title.focus();
await title.pressSequentially('test3', {
delay: 100,
});
}
{
await expect(getBlockSuiteEditorTitle(page)).toHaveText('test3');
}
await page.click('[data-testid="app-navigation-button-back"]');
await page.click('[data-testid="app-navigation-button-back"]');
{
await expect(getBlockSuiteEditorTitle(page)).toHaveText('test1');
}
await page.click('[data-testid="app-navigation-button-forward"]');
await page.click('[data-testid="app-navigation-button-forward"]');
{
await expect(getBlockSuiteEditorTitle(page)).toHaveText('test3');
}
await historyShortcut(page, 'goBack');
await historyShortcut(page, 'goBack');
{
await expect(getBlockSuiteEditorTitle(page)).toHaveText('test1');
}
await historyShortcut(page, 'goForward');
await historyShortcut(page, 'goForward');
{
await expect(getBlockSuiteEditorTitle(page)).toHaveText('test3');
}
});
test('clientBorder value should disable by default on window', async ({
page,
}) => {
await clickSideBarSettingButton(page);
await page.waitForTimeout(1000);
const settingItem = page.locator(
'[data-testid="client-border-style-trigger"]'
);
expect(await settingItem.locator('input').inputValue()).toEqual(
process.platform === 'win32' ? 'off' : 'on'
);
});
test('app theme', async ({ page, electronApp }) => {
2023-04-28 09:40:44 +03:00
const root = page.locator('html');
{
const themeMode = await root.evaluate(element => element.dataset.theme);
2023-04-28 09:40:44 +03:00
expect(themeMode).toBe('light');
const theme = await electronApp.evaluate(({ nativeTheme }) => {
return nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
});
expect(theme).toBe('light');
2023-04-28 09:40:44 +03:00
}
2023-04-28 09:40:44 +03:00
{
2023-07-31 10:56:51 +03:00
await page.getByTestId('settings-modal-trigger').click();
await page.getByTestId('appearance-panel-trigger').click();
await page.waitForTimeout(50);
2023-07-31 10:56:51 +03:00
await page.getByTestId('dark-theme-trigger').click();
const themeMode = await root.evaluate(element => element.dataset.theme);
expect(themeMode).toBe('dark');
const theme = await electronApp.evaluate(({ nativeTheme }) => {
return nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
});
expect(theme).toBe('dark');
2023-04-28 09:40:44 +03:00
}
});
2023-06-29 19:15:44 +03:00
test('windows only check', async ({ page }) => {
const windowOnlyUI = page.locator('[data-platform-target=win32]');
if (process.platform === 'win32') {
feat(component): new right sidebar (#5169) Refactor AFFiNE layout to support new right sidebar. The new layout: ![image](https://github.com/toeverything/AFFiNE/assets/584378/678a05f5-bd48-4dbe-ad78-7a0bcc979918) **Highlights:** - new sidebar UI/UX - favoring top-down UI components that are composed by basic building blocks in each route, instead of creating universal component like `WorkspaceHeader` that renders every possible cases (which I think is really hard to maintain) - remove plugin based solution **Pros/cons for current plugin-based solution:** The current solution is somewhat a Dependency Injection (DI) approach, where the layout is defined at the top and UI items can be injected using Jotai atom slots. This approach works well if we want a fully configurable system with everything being handled by plugins. It provides flexibility for custom extensions. However, this solution is more suitable for single-page applications where the UI is completely controlled by configuration. It becomes challenging to achieve an optimized and visually appealing UI that remains under our control. An example of such a scenario would be a customizable dashboard like Grafana. Another drawback of the existing solution is that we need to use Jotai and hooks to access context values, resulting in an unclear data flow within the component hierarchy. **Alternatively, our approach in this PR** provides layout building blocks such as headers and sidebars, which can then be composed in individual route components. The good is that we have cleaner biz component instead of vague all-in-one layout component (like `<WorkspaceHeader />`). **Issues of the implementation in this PR:** Some UI layouts that that seems to be defined at the root layout are now defined in individual route component instead. New 3-col layout component like the right sidebar still needs some abstraction and they are right now just for the detail editor only.
2023-12-08 04:03:47 +03:00
await expect(windowOnlyUI.first()).toBeVisible();
2023-06-29 19:15:44 +03:00
} else {
feat(component): new right sidebar (#5169) Refactor AFFiNE layout to support new right sidebar. The new layout: ![image](https://github.com/toeverything/AFFiNE/assets/584378/678a05f5-bd48-4dbe-ad78-7a0bcc979918) **Highlights:** - new sidebar UI/UX - favoring top-down UI components that are composed by basic building blocks in each route, instead of creating universal component like `WorkspaceHeader` that renders every possible cases (which I think is really hard to maintain) - remove plugin based solution **Pros/cons for current plugin-based solution:** The current solution is somewhat a Dependency Injection (DI) approach, where the layout is defined at the top and UI items can be injected using Jotai atom slots. This approach works well if we want a fully configurable system with everything being handled by plugins. It provides flexibility for custom extensions. However, this solution is more suitable for single-page applications where the UI is completely controlled by configuration. It becomes challenging to achieve an optimized and visually appealing UI that remains under our control. An example of such a scenario would be a customizable dashboard like Grafana. Another drawback of the existing solution is that we need to use Jotai and hooks to access context values, resulting in an unclear data flow within the component hierarchy. **Alternatively, our approach in this PR** provides layout building blocks such as headers and sidebars, which can then be composed in individual route components. The good is that we have cleaner biz component instead of vague all-in-one layout component (like `<WorkspaceHeader />`). **Issues of the implementation in this PR:** Some UI layouts that that seems to be defined at the root layout are now defined in individual route component instead. New 3-col layout component like the right sidebar still needs some abstraction and they are right now just for the detail editor only.
2023-12-08 04:03:47 +03:00
await expect(windowOnlyUI.first()).not.toBeVisible();
2023-06-29 19:15:44 +03:00
}
});
test('delete workspace', async ({ page }) => {
await clickSideBarCurrentWorkspaceBanner(page);
await page.getByTestId('new-workspace').click();
2023-12-15 10:20:50 +03:00
await page.getByTestId('create-workspace-input').fill('Delete Me');
await page.getByTestId('create-workspace-create-button').click();
// await page.getByTestId('create-workspace-continue-button').click({
// delay: 100,
// });
await page.waitForTimeout(1000);
await clickSideBarSettingButton(page);
await page.getByTestId('current-workspace-label').click();
2023-12-18 15:24:48 +03:00
await expect(page.getByTestId('workspace-name-input')).toHaveValue(
'Delete Me'
);
const contentElement = page.getByTestId('setting-modal-content');
const boundingBox = await contentElement.boundingBox();
if (!boundingBox) {
throw new Error('boundingBox is null');
}
await page.mouse.move(
boundingBox.x + boundingBox.width / 2,
boundingBox.y + boundingBox.height / 2
);
await page.mouse.wheel(0, 500);
await page.getByTestId('delete-workspace-button').click();
2023-12-15 10:20:50 +03:00
await page.getByTestId('delete-workspace-input').fill('Delete Me');
await page.getByTestId('delete-workspace-confirm-button').click();
await page.waitForTimeout(1000);
expect(await page.getByTestId('workspace-name').textContent()).toBe(
'Demo Workspace'
);
});
// temporary way to enable split view
async function enableSplitView(page: Page) {
await page.evaluate(() => {
const settingKey = 'affine-settings';
window.localStorage.setItem(
settingKey,
JSON.stringify({
clientBorder: false,
fullWidthLayout: false,
windowFrameStyle: 'frameless',
fontStyle: 'Serif',
dateFormat: 'MM/dd/YYYY',
startWeekOnMonday: false,
enableBlurBackground: true,
enableNoisyBackground: true,
autoCheckUpdate: true,
autoDownloadUpdate: true,
enableMultiView: true,
editorFlags: {},
})
);
});
await page.reload();
}
test('open split view', async ({ page }) => {
await enableSplitView(page);
await page.getByTestId('sidebar-new-page-button').click({
delay: 100,
});
await waitForEmptyEditor(page);
await page.waitForTimeout(500);
await page.keyboard.press('Enter');
await createLinkedPage(page, 'hi from another page');
await page
.locator('.affine-reference-title:has-text("hi from another page")')
.click({
modifiers: [process.platform === 'darwin' ? 'Meta' : 'Control'],
});
await expect(page.locator('.doc-title-container')).toHaveCount(2);
});