[go: nahoru, domu]

Skip to content

Commit

Permalink
test: improve e2e test stability and add terminal test case (#1710)
Browse files Browse the repository at this point in the history
* test: improve exist e2e test case

* chore: remove CollaborationModule from startup

* test: add terminal case

* test: add auto search case

* test: improve terminal test case

* chore: cd workspace path on terminal

* chore: update user key typing delay

* chore: update playwright viewport
  • Loading branch information
erha19 authored Oct 8, 2022
1 parent 5511c0c commit 94ac126
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 31 deletions.
3 changes: 1 addition & 2 deletions packages/startup/entry/web/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ setLocale('en-US');

import '@opensumi/ide-i18n';
import '@opensumi/ide-core-browser/lib/style/index.less';
import { CollaborationModule } from '@opensumi/ide-collaboration/lib/browser';
import { SlotLocation } from '@opensumi/ide-core-browser';
import { ExpressFileServerModule } from '@opensumi/ide-express-file-server/lib/browser';
import { defaultConfig } from '@opensumi/ide-main-layout/lib/browser/default-config';
Expand All @@ -20,7 +19,7 @@ import { renderApp } from './render-app';
import '../styles.less';

renderApp({
modules: [...CommonBrowserModules, ExpressFileServerModule, SampleModule, RemoteOpenerModule, CollaborationModule],
modules: [...CommonBrowserModules, ExpressFileServerModule, SampleModule, RemoteOpenerModule],
layoutConfig: {
...defaultConfig,
...{
Expand Down
4 changes: 1 addition & 3 deletions packages/startup/entry/web/server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { startServer } from '@opensumi/ide-dev-tool/src/server';
// eslint-disable-next-line import/order
import { CollaborationModule } from '@opensumi/ide-collaboration/lib/node';
import { ExpressFileServerModule } from '@opensumi/ide-express-file-server/lib/node';
import { OpenerModule } from '@opensumi/ide-remote-opener/lib/node';

import { CommonNodeModules } from '../../src/node/common-modules';

startServer({
modules: [...CommonNodeModules, ExpressFileServerModule, OpenerModule, CollaborationModule],
modules: [...CommonNodeModules, ExpressFileServerModule, OpenerModule],
});
1 change: 1 addition & 0 deletions tools/playwright/configs/playwright.ci.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const ciConfig: PlaywrightTestConfig = {
...baseConfig,
workers: 1,
retries: 1,
maxFailures: process.env.CI ? 10 : undefined,
};

export default ciConfig;
2 changes: 1 addition & 1 deletion tools/playwright/configs/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const config: PlaywrightTestConfig = {
baseURL: 'http://localhost:8080',
browserName: 'chromium',
screenshot: 'only-on-failure',
viewport: { width: 1920, height: 1080 },
viewport: { width: 1280, height: 720 },
},
snapshotDir: path.join(__dirname, '../src/tests/snapshots'),
expect: {
Expand Down
17 changes: 15 additions & 2 deletions tools/playwright/src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class OpenSumiEditor extends OpenSumiView {

async open(preview?: boolean) {
await this.filestatElement.open(preview);
// waiting editor render
await this.app.page.waitForTimeout(200);
return this;
}

Expand All @@ -29,7 +31,8 @@ export class OpenSumiEditor extends OpenSumiView {

async isDirty() {
const dirtyIcon = await (await this.getCurrentTab())?.$("[class*='dirty___']");
const hidden = (await dirtyIcon?.getAttribute('class'))?.includes('hidden__');
const className = await dirtyIcon?.getAttribute('class');
const hidden = className?.includes('hidden__');
return !hidden;
}

Expand All @@ -38,11 +41,21 @@ export class OpenSumiEditor extends OpenSumiView {
if (!(await this.isDirty())) {
return;
}
const dirtyIcon = await (await this.getCurrentTab())?.$("[class*='dirty___']");
await this.app.menubar.trigger('File', 'Save File');
// waiting for saved
await dirtyIcon?.waitForElementState('hidden');
}

async close() {
const closeIcon = await (await this.getTabElement())?.waitForSelector("class*=['close_tab___']");
const currentTab = await this.getTabElement();
await currentTab?.hover({
position: {
x: 10,
y: 10,
},
});
const closeIcon = await currentTab?.$("[class*='close_tab___']");
await closeIcon?.click();
}

Expand Down
4 changes: 1 addition & 3 deletions tools/playwright/src/explorer-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ export class OpenSumiExplorerFileStatNode extends OpenSumiTreeNode {
}

export class OpenSumiExplorerView extends OpenSumiPanel {
id = 'explorer';

private _fileTreeView: OpenSumiView;

constructor(app: OpenSumiApp) {
super(app);
super(app, 'explorer');
}

initFileTreeView(name: string) {
Expand Down
4 changes: 2 additions & 2 deletions tools/playwright/src/menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export class OpenSumiMenuItem {
constructor(protected element: ElementHandle<SVGElement | HTMLElement>) {}

protected labelElementHandle() {
return this.element.waitForSelector("[class*='label__']");
return this.element.$("[class*='label__']");
}

protected shortCutElementHandle() {
return this.element.waitForSelector("[class*='shortcut__']");
return this.element.$("[class*='shortcut__']");
}

async label() {
Expand Down
21 changes: 14 additions & 7 deletions tools/playwright/src/panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@ import { OpenSumiApp } from './app';
import { OpenSumiViewBase } from './view-base';

export abstract class OpenSumiPanel extends OpenSumiViewBase {
private view: ElementHandle<HTMLElement | SVGElement> | null;
public view: ElementHandle<HTMLElement | SVGElement> | null;
private whenReady: Promise<void>;

abstract id: string;

constructor(app: OpenSumiApp) {
constructor(app: OpenSumiApp, private viewId: string) {
super(app);
this.whenReady = this.init();
}

get viewSelector() {
return `.${this.id}`;
return `.${this.viewId}`;
}

async init() {
Expand All @@ -28,15 +26,24 @@ export abstract class OpenSumiPanel extends OpenSumiViewBase {
}

async open() {
if (!this.id) {
if (!this.viewId) {
return;
}
await this.app.quickOpenPalette.type('view ');
await this.app.quickOpenPalette.trigger(this.id.toLocaleUpperCase());
await this.app.quickOpenPalette.trigger(this.viewId.toLocaleUpperCase());
await this.waitForVisible();
this.view = await this.page.$(this.viewSelector);
return this;
}

async focus() {
const visible = await this.isVisible();
if (!visible) {
await this.open();
}
await this.view?.focus();
}

async waitForVisible() {
await this.page.waitForSelector(this.viewSelector, { state: 'visible' });
}
Expand Down
2 changes: 1 addition & 1 deletion tools/playwright/src/quick-command-palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { OPENSUMI_VIEW_CONTAINERS } from './constans';
import { OpenSumiViewBase } from './view-base';

export class OpenSumiCommandPalette extends OpenSumiViewBase {
static USER_KEY_TYPING_DELAY = 100;
static USER_KEY_TYPING_DELAY = 200;

async open() {
await this.page.keyboard.press(isMacintosh ? 'Meta+Shift+p' : 'Control+Shift+p');
Expand Down
2 changes: 1 addition & 1 deletion tools/playwright/src/quick-open-palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { OPENSUMI_VIEW_CONTAINERS } from './constans';
import { OpenSumiViewBase } from './view-base';

export class OpenSumiQuickOpenPalette extends OpenSumiViewBase {
static USER_KEY_TYPING_DELAY = 100;
static USER_KEY_TYPING_DELAY = 200;

async open() {
await this.page.keyboard.press(isMacintosh ? 'Meta+p' : 'Control+p');
Expand Down
41 changes: 40 additions & 1 deletion tools/playwright/src/search-view.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
import { OpenSumiApp } from './app';
import { OpenSumiPanel } from './panel';

export class OpenSumiSearchView extends OpenSumiPanel {
id = 'search';
constructor(app: OpenSumiApp) {
super(app, 'search');
}

get searchInputSelector() {
return '#search-input-field';
}

get replaceInputSelector() {
return '#replace-input-field';
}

async getSearchResult() {
let results;
let files;
const resultElement = await this.app.page.waitForSelector('[class*="result_describe__"]');
const text = await resultElement.textContent();
const regx = /^(\d+) results found in (\d+) files/gi;
if (text) {
const match = regx.exec(text);
if (match) {
results = Number(match[1]);
files = Number(match[2]);
}
}
return {
results,
files,
};
}

async focusOnSearch() {
const visible = await this.isVisible();
if (!visible) {
await this.open();
}
const $searchInput = await this.app.page.$(this.searchInputSelector);
await $searchInput?.focus();
}
}
22 changes: 22 additions & 0 deletions tools/playwright/src/terminal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { OpenSumiApp } from './app';
import { OpenSumiPanel } from './panel';

export class OpenSumiTerminal extends OpenSumiPanel {
constructor(app: OpenSumiApp) {
super(app, 'terminal');
}

async sendText(text: string) {
const visible = await this.isVisible();
if (!visible) {
await this.open();
}
await this.focus();
const box = await this.view?.boundingBox();
if (box) {
await this.app.page.mouse.click(box.x + box?.width / 2, box.y + box?.height / 2);
}
await this.page.keyboard.type(text);
await this.app.page.keyboard.press('Enter');
}
}
11 changes: 9 additions & 2 deletions tools/playwright/src/tests/editor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,18 @@ test.describe('OpenSumi Editor', () => {
editor = await app.openEditor(OpenSumiTextEditor, explorer, 'editor.js');
const isPreview = await editor.isPreview();
expect(isPreview).toBeTruthy();
await editor.close();
});

test('open editor.js on the editor without preview', async () => {
editor = await app.openEditor(OpenSumiTextEditor, explorer, 'editor.js', false);
const isPreview = await editor.isPreview();
expect(isPreview).toBeFalsy();
await editor.close();
});

test('editor dirty status should be update immediately after typing and saving', async () => {
editor = await app.openEditor(OpenSumiTextEditor, explorer, 'editor.js');
await editor.addTextToNewLineAfterLineByLineNumber(
1,
`const a = 'a';
Expand All @@ -49,9 +52,9 @@ console.log(a);`,
let isDirty = await editor.isDirty();
expect(isDirty).toBeTruthy();
await editor.save();
await app.page.waitForTimeout(200);
isDirty = await editor.isDirty();
expect(isDirty).toBeFalsy();
await editor.close();
});

test('copy path from file explorer to the editor content', async () => {
Expand All @@ -60,6 +63,7 @@ console.log(a);`,
expect(await fileMenu?.isOpen()).toBeTruthy();
const copyPath = await fileMenu?.menuItemByName('Copy Path');
await copyPath?.click();
editor = await app.openEditor(OpenSumiTextEditor, explorer, 'editor.js');
await editor.addTextToNewLineAfterLineByLineNumber(3, 'File Path: ');
// cause of https://github.com/microsoft/playwright/issues/8114
// we can just using keypress to fake the paste feature
Expand Down Expand Up @@ -90,13 +94,16 @@ console.log(a);`,

test('Go to Symbol... should be worked', async () => {
editor = await app.openEditor(OpenSumiTextEditor, explorer, 'editor2.js');
// waiting for extHost process done.
await app.page.waitForTimeout(1000);
const editorMenu = await editor.openLineContextMenuByLineNumber(1);
expect(await editorMenu?.isOpen()).toBeTruthy();
const goto = await editorMenu?.menuItemByName('Go to Symbol...');
await goto?.click();
await app.page.waitForTimeout(200);
await app.page.waitForTimeout(1000);
const input = await app.page.waitForSelector(`#${OPENSUMI_VIEW_CONTAINERS.QUICKPICK_INPUT}`);
await input.focus();
await app.page.keyboard.press(' ');
await app.page.keyboard.press('ArrowDown');
await app.page.keyboard.press('ArrowDown');
await app.page.keyboard.press('Enter');
Expand Down
20 changes: 17 additions & 3 deletions tools/playwright/src/tests/explorer-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import path from 'path';

import { expect } from '@playwright/test';

import { isWindows } from '@opensumi/ide-utils';

import { OpenSumiApp } from '../app';
import { OpenSumiExplorerView } from '../explorer-view';
import { OpenSumiTerminal } from '../terminal';
import { OpenSumiView } from '../view';
import { OpenSumiWorkspace } from '../workspace';

Expand All @@ -12,10 +15,11 @@ import test, { page } from './hooks';
let app: OpenSumiApp;
let explorer: OpenSumiExplorerView;
let fileTreeView: OpenSumiView;
let workspace: OpenSumiWorkspace;

test.describe('OpenSumi Explorer Panel', () => {
test.beforeAll(async () => {
const workspace = new OpenSumiWorkspace([path.resolve('./src/tests/workspaces/default')]);
workspace = new OpenSumiWorkspace([path.resolve('./src/tests/workspaces/default')]);
app = await OpenSumiApp.load(page, workspace);
explorer = await app.open(OpenSumiExplorerView);
explorer.initFileTreeView(workspace.workspace.displayName);
Expand All @@ -29,7 +33,7 @@ test.describe('OpenSumi Explorer Panel', () => {
test('should show file explorer', async () => {
expect(explorer.isVisible()).toBeTruthy();
await fileTreeView.open();
expect(fileTreeView.isVisible()).toBeTruthy();
expect(await fileTreeView.isVisible()).toBeTruthy();
});

test('can new single file by context menu', async () => {
Expand Down Expand Up @@ -69,7 +73,7 @@ test.describe('OpenSumi Explorer Panel', () => {
const newFileMenu = await menu?.menuItemByName('New Folder');
await newFileMenu?.click();
// type `new_file` as the file name
const newFileName = 'new_Folder';
const newFileName = 'new_folder';
const input = await (await fileTreeView.getViewElement())?.waitForSelector('.kt-input-box');
if (input != null) {
await input.focus();
Expand All @@ -81,4 +85,14 @@ test.describe('OpenSumi Explorer Panel', () => {
expect(newFile).toBeDefined();
expect(await newFile?.isFolder()).toBeTruthy();
});

(isWindows ? test.skip : test)('fileTree should be updated while create directory from terminal', async () => {
const dirname = 'dir_from_terminal';
const terminal = await app.open(OpenSumiTerminal);
await terminal.sendText(`cd ${workspace.workspace.codeUri.fsPath}`);
await terminal.sendText(`mkdir ${dirname}`);
await app.page.waitForTimeout(2000);
const newDir = await explorer.getFileStatTreeNodeByPath(dirname);
expect(newDir).toBeDefined();
});
});
12 changes: 10 additions & 2 deletions tools/playwright/src/tests/search-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ test.describe('OpenSumi Search Panel', () => {
search = await app.open(OpenSumiSearchView);
});

test('Can search files by simple text', () => {
expect(search.isVisible()).toBeTruthy();
test('Can search files by simple text', async () => {
const searchText = 'hello';
expect(await search.isVisible()).toBeTruthy();
await search.focusOnSearch();
await page.keyboard.type(searchText);
// search panel should searched after typing
await app.page.keyboard.press('Enter');
const { results, files } = await search.getSearchResult();
expect(results).toBe(1);
expect(files).toBe(1);
});
});
2 changes: 1 addition & 1 deletion tools/playwright/src/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class OpenSumiWorkspace extends Disposable {
track.cleanupSync();
},
});
this.workspacePath = path.join(temp.mkdirSync('workspace'));
this.workspacePath = fse.realpathSync(path.join(temp.mkdirSync('workspace')));
}

get workspace() {
Expand Down

0 comments on commit 94ac126

Please sign in to comment.