@opensumi/playwright 2.21.13 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app.d.ts +2 -1
- package/lib/app.d.ts.map +1 -1
- package/lib/app.js +21 -9
- package/lib/app.js.map +1 -1
- package/lib/component-editor.d.ts +2 -2
- package/lib/debug-view.d.ts +10 -0
- package/lib/debug-view.d.ts.map +1 -1
- package/lib/debug-view.js +41 -1
- package/lib/debug-view.js.map +1 -1
- package/lib/diff-editor.d.ts +4 -0
- package/lib/diff-editor.d.ts.map +1 -0
- package/lib/diff-editor.js +8 -0
- package/lib/diff-editor.js.map +1 -0
- package/lib/editor.d.ts +6 -5
- package/lib/editor.d.ts.map +1 -1
- package/lib/editor.js +6 -2
- package/lib/editor.js.map +1 -1
- package/lib/explorer-view.d.ts +4 -0
- package/lib/explorer-view.d.ts.map +1 -1
- package/lib/explorer-view.js +36 -10
- package/lib/explorer-view.js.map +1 -1
- package/lib/filetree-view.d.ts +1 -1
- package/lib/filetree-view.js +2 -2
- package/lib/filetree-view.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/menu.d.ts +1 -1
- package/lib/opened-editor-view.d.ts +2 -2
- package/lib/opened-editor-view.d.ts.map +1 -1
- package/lib/opened-editor-view.js +4 -4
- package/lib/opened-editor-view.js.map +1 -1
- package/lib/outline-view.d.ts +9 -0
- package/lib/outline-view.d.ts.map +1 -0
- package/lib/outline-view.js +38 -0
- package/lib/outline-view.js.map +1 -0
- package/lib/output-view.d.ts +10 -0
- package/lib/output-view.d.ts.map +1 -0
- package/lib/output-view.js +78 -0
- package/lib/output-view.js.map +1 -0
- package/lib/panel.js +2 -2
- package/lib/panel.js.map +1 -1
- package/lib/scm-view.d.ts +21 -0
- package/lib/scm-view.d.ts.map +1 -0
- package/lib/scm-view.js +65 -0
- package/lib/scm-view.js.map +1 -0
- package/lib/search-view.d.ts +34 -0
- package/lib/search-view.d.ts.map +1 -1
- package/lib/search-view.js +196 -4
- package/lib/search-view.js.map +1 -1
- package/lib/source-control-view.d.ts +8 -0
- package/lib/source-control-view.d.ts.map +1 -0
- package/lib/source-control-view.js +45 -0
- package/lib/source-control-view.js.map +1 -0
- package/lib/terminal-view.d.ts +10 -0
- package/lib/terminal-view.d.ts.map +1 -0
- package/lib/terminal-view.js +50 -0
- package/lib/terminal-view.js.map +1 -0
- package/lib/tests/debug.test.js +49 -0
- package/lib/tests/debug.test.js.map +1 -1
- package/lib/tests/editor/undoRedo.test.d.ts +2 -0
- package/lib/tests/editor/undoRedo.test.d.ts.map +1 -0
- package/lib/tests/editor/undoRedo.test.js +52 -0
- package/lib/tests/editor/undoRedo.test.js.map +1 -0
- package/lib/tests/editor.test.js +0 -2
- package/lib/tests/editor.test.js.map +1 -1
- package/lib/tests/explorer-view.test.js +129 -5
- package/lib/tests/explorer-view.test.js.map +1 -1
- package/lib/tests/output.test.d.ts +2 -0
- package/lib/tests/output.test.d.ts.map +1 -0
- package/lib/tests/output.test.js +76 -0
- package/lib/tests/output.test.js.map +1 -0
- package/lib/tests/scm.test.js +42 -4
- package/lib/tests/scm.test.js.map +1 -1
- package/lib/tests/search-view.test.js +191 -8
- package/lib/tests/search-view.test.js.map +1 -1
- package/lib/tests/settings.test.d.ts +2 -0
- package/lib/tests/settings.test.d.ts.map +1 -0
- package/lib/tests/settings.test.js +95 -0
- package/lib/tests/settings.test.js.map +1 -0
- package/lib/text-editor.d.ts +7 -3
- package/lib/text-editor.d.ts.map +1 -1
- package/lib/text-editor.js +15 -0
- package/lib/text-editor.js.map +1 -1
- package/lib/tree-node.d.ts +3 -1
- package/lib/tree-node.d.ts.map +1 -1
- package/lib/tree-node.js +4 -4
- package/lib/tree-node.js.map +1 -1
- package/lib/utils/key.d.ts +1 -0
- package/lib/utils/key.d.ts.map +1 -1
- package/lib/utils/key.js +6 -1
- package/lib/utils/key.js.map +1 -1
- package/lib/view.js +1 -1
- package/lib/view.js.map +1 -1
- package/package.json +12 -11
- package/src/app.ts +148 -0
- package/src/component-editor.ts +64 -0
- package/src/constans/index.ts +18 -0
- package/src/context-menu.ts +27 -0
- package/src/debug-view.ts +73 -0
- package/src/diff-editor.ts +3 -0
- package/src/editor.ts +135 -0
- package/src/explorer-view.ts +149 -0
- package/src/filetree-view.ts +28 -0
- package/src/index.ts +20 -0
- package/src/menu-item.ts +40 -0
- package/src/menu.ts +69 -0
- package/src/menubar.ts +53 -0
- package/src/opened-editor-view.ts +28 -0
- package/src/outline-view.ts +37 -0
- package/src/output-view.ts +76 -0
- package/src/panel.ts +50 -0
- package/src/quick-command-palette.ts +62 -0
- package/src/quick-open-palette.ts +62 -0
- package/src/scm-view.ts +72 -0
- package/src/search-view.ts +260 -0
- package/src/source-control-view.ts +44 -0
- package/src/terminal-view.ts +50 -0
- package/src/tests/app.test.ts +16 -0
- package/src/tests/debug.test.ts +121 -0
- package/src/tests/editor/undoRedo.test.ts +55 -0
- package/src/tests/editor.test.ts +141 -0
- package/src/tests/explorer-view.test.ts +329 -0
- package/src/tests/hooks/index.ts +13 -0
- package/src/tests/keymaps.test.ts +118 -0
- package/src/tests/language.test.ts +55 -0
- package/src/tests/output.test.ts +87 -0
- package/src/tests/scm.test.ts +84 -0
- package/src/tests/search-view.test.ts +239 -0
- package/src/tests/settings.test.ts +115 -0
- package/src/tests/workspaces/debug/.sumi/launch.json +15 -0
- package/src/tests/workspaces/debug/index.js +18 -0
- package/src/tests/workspaces/default/editor-undo-redo.text +0 -0
- package/src/tests/workspaces/default/editor.js +0 -0
- package/src/tests/workspaces/default/editor2.js +87 -0
- package/src/tests/workspaces/default/editor3.js +0 -0
- package/src/tests/workspaces/default/test/test.js +1 -0
- package/src/tests/workspaces/git-workspace/a.js +0 -0
- package/src/tests/workspaces/language/definition.ts +12 -0
- package/src/tests/workspaces/language/reference.ts +9 -0
- package/src/tests/workspaces/search/index.js +5 -0
- package/src/tests/workspaces/search/index2.js +1 -0
- package/src/text-editor.ts +333 -0
- package/src/tree-node.ts +98 -0
- package/src/utils/element.ts +35 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/key.ts +11 -0
- package/src/view-base.ts +11 -0
- package/src/view.ts +90 -0
- package/src/workspace.ts +36 -0
- package/lib/terminal.d.ts +0 -7
- package/lib/terminal.d.ts.map +0 -1
- package/lib/terminal.js +0 -25
- package/lib/terminal.js.map +0 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import { expect } from '@playwright/test';
|
|
4
|
+
|
|
5
|
+
import { OpenSumiApp } from '../app';
|
|
6
|
+
import { OpenSumiExplorerView } from '../explorer-view';
|
|
7
|
+
import { OpenSumiFileTreeView } from '../filetree-view';
|
|
8
|
+
import { OpenSumiOutputView } from '../output-view';
|
|
9
|
+
import { keypressWithCmdCtrl } from '../utils/key';
|
|
10
|
+
import { OpenSumiWorkspace } from '../workspace';
|
|
11
|
+
|
|
12
|
+
import test, { page } from './hooks';
|
|
13
|
+
|
|
14
|
+
let app: OpenSumiApp;
|
|
15
|
+
let explorer: OpenSumiExplorerView;
|
|
16
|
+
let fileTreeView: OpenSumiFileTreeView;
|
|
17
|
+
let workspace: OpenSumiWorkspace;
|
|
18
|
+
let output: OpenSumiOutputView;
|
|
19
|
+
|
|
20
|
+
test.describe('OpenSumi Output View', () => {
|
|
21
|
+
test.beforeAll(async () => {
|
|
22
|
+
workspace = new OpenSumiWorkspace([path.resolve('./src/tests/workspaces/language')]);
|
|
23
|
+
app = await OpenSumiApp.load(page, workspace);
|
|
24
|
+
explorer = await app.open(OpenSumiExplorerView);
|
|
25
|
+
explorer.initFileTreeView(workspace.workspace.displayName);
|
|
26
|
+
fileTreeView = explorer.fileTreeView;
|
|
27
|
+
output = await app.open(OpenSumiOutputView);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test.afterAll(() => {
|
|
31
|
+
app.dispose();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('should show file explorer and output panel', async () => {
|
|
35
|
+
expect(await output.isVisible()).toBeTruthy();
|
|
36
|
+
await fileTreeView.open();
|
|
37
|
+
expect(await fileTreeView.isVisible()).toBeTruthy();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('get `TypeScript` channel output content', async () => {
|
|
41
|
+
const node = await explorer.getFileStatTreeNodeByPath('reference.ts');
|
|
42
|
+
await node?.open();
|
|
43
|
+
await page.waitForTimeout(1000);
|
|
44
|
+
|
|
45
|
+
await output.setChannel('TypeScript');
|
|
46
|
+
const content = await output.getCurrentContent();
|
|
47
|
+
expect(content?.includes('tsserver')).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('can search text from output', async () => {
|
|
51
|
+
// Focus Output content
|
|
52
|
+
await output.focus();
|
|
53
|
+
const box = await output.view?.boundingBox();
|
|
54
|
+
if (box) {
|
|
55
|
+
await output.app.page.mouse.click(box.x + box?.width / 2, box.y + box?.height / 2);
|
|
56
|
+
}
|
|
57
|
+
await app.page.keyboard.press(keypressWithCmdCtrl('KeyF'));
|
|
58
|
+
const textArea = await output.view?.$('.monaco-inputbox textarea');
|
|
59
|
+
await textArea?.focus();
|
|
60
|
+
await textArea?.type('tsserver', { delay: 200 });
|
|
61
|
+
|
|
62
|
+
let selected = await output.view?.$('.selected-text');
|
|
63
|
+
expect(selected).toBeDefined();
|
|
64
|
+
|
|
65
|
+
await textArea?.focus();
|
|
66
|
+
await app.page.keyboard.press('Escape');
|
|
67
|
+
if (box) {
|
|
68
|
+
await output.app.page.mouse.click(box.x + box?.width / 2, box.y + box?.height / 2);
|
|
69
|
+
}
|
|
70
|
+
selected = await output.view?.$('.selected-text');
|
|
71
|
+
expect(selected).toBeNull();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('clean output content', async () => {
|
|
75
|
+
const node = await explorer.getFileStatTreeNodeByPath('definition.ts');
|
|
76
|
+
await node?.open();
|
|
77
|
+
await page.waitForTimeout(1000);
|
|
78
|
+
|
|
79
|
+
await output.setChannel('TypeScript');
|
|
80
|
+
let content = await output.getCurrentContent();
|
|
81
|
+
expect(content?.includes('tsserver')).toBeTruthy();
|
|
82
|
+
|
|
83
|
+
await output.clean();
|
|
84
|
+
content = await output.getCurrentContent();
|
|
85
|
+
expect(content?.includes('tsserver')).toBeFalsy();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import { expect } from '@playwright/test';
|
|
4
|
+
|
|
5
|
+
import { OpenSumiApp } from '../app';
|
|
6
|
+
import { OpenSumiDiffEditor } from '../diff-editor';
|
|
7
|
+
import { OpenSumiExplorerView } from '../explorer-view';
|
|
8
|
+
import { OpenSumiFileTreeView } from '../filetree-view';
|
|
9
|
+
import { OpenSumiSCMView } from '../scm-view';
|
|
10
|
+
import { OpenSumiTerminalView } from '../terminal-view';
|
|
11
|
+
import { OpenSumiWorkspace } from '../workspace';
|
|
12
|
+
|
|
13
|
+
import test, { page } from './hooks';
|
|
14
|
+
|
|
15
|
+
let app: OpenSumiApp;
|
|
16
|
+
let explorer: OpenSumiExplorerView;
|
|
17
|
+
let scm: OpenSumiSCMView;
|
|
18
|
+
let fileTreeView: OpenSumiFileTreeView;
|
|
19
|
+
let workspace: OpenSumiWorkspace;
|
|
20
|
+
|
|
21
|
+
test.describe('OpenSumi SCM Panel', () => {
|
|
22
|
+
test.beforeAll(async () => {
|
|
23
|
+
workspace = new OpenSumiWorkspace([path.resolve('./src/tests/workspaces/git-workspace')]);
|
|
24
|
+
app = await OpenSumiApp.load(page, workspace);
|
|
25
|
+
explorer = await app.open(OpenSumiExplorerView);
|
|
26
|
+
explorer.initFileTreeView(workspace.workspace.displayName);
|
|
27
|
+
fileTreeView = explorer.fileTreeView;
|
|
28
|
+
const terminal = await app.open(OpenSumiTerminalView);
|
|
29
|
+
// There should have GIT on the PATH
|
|
30
|
+
await terminal.sendText('git init');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test.afterAll(() => {
|
|
34
|
+
app.dispose();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('The "U" charset should on the files tail after git initialized', async () => {
|
|
38
|
+
await explorer.fileTreeView.open();
|
|
39
|
+
const action = await fileTreeView.getTitleActionByName('Refresh');
|
|
40
|
+
await action?.click();
|
|
41
|
+
await app.page.waitForTimeout(2000);
|
|
42
|
+
const node = await explorer.getFileStatTreeNodeByPath('a.js');
|
|
43
|
+
const badge = await node?.badge();
|
|
44
|
+
expect(badge).toBe('U');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('The "U" charset should on the files tail on SCM view', async () => {
|
|
48
|
+
scm = await app.open(OpenSumiSCMView);
|
|
49
|
+
await scm.open();
|
|
50
|
+
await app.page.waitForTimeout(2000);
|
|
51
|
+
const node = await scm.getFileStatTreeNodeByPath('a.js');
|
|
52
|
+
const badge = await node?.getBadge();
|
|
53
|
+
expect(badge).toBe('U');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('Open file from context menu', async () => {
|
|
57
|
+
scm = await app.open(OpenSumiSCMView);
|
|
58
|
+
await scm.open();
|
|
59
|
+
const node = await scm.getFileStatTreeNodeByPath('a.js');
|
|
60
|
+
const item = await node?.getMenuItemByName('Open File');
|
|
61
|
+
await item?.click();
|
|
62
|
+
await app.page.waitForTimeout(1000);
|
|
63
|
+
if (node) {
|
|
64
|
+
const editor = new OpenSumiDiffEditor(app, node);
|
|
65
|
+
const currentTab = await editor.getCurrentTab();
|
|
66
|
+
const dataUri = await currentTab?.getAttribute('data-uri');
|
|
67
|
+
expect(dataUri?.startsWith('file')).toBeTruthy();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('Open file with diff editor', async () => {
|
|
72
|
+
scm = await app.open(OpenSumiSCMView);
|
|
73
|
+
await scm.open();
|
|
74
|
+
const node = await scm.getFileStatTreeNodeByPath('a.js');
|
|
75
|
+
await node?.open();
|
|
76
|
+
await app.page.waitForTimeout(1000);
|
|
77
|
+
if (node) {
|
|
78
|
+
const editor = new OpenSumiDiffEditor(app, node);
|
|
79
|
+
const currentTab = await editor.getCurrentTab();
|
|
80
|
+
const dataUri = await currentTab?.getAttribute('data-uri');
|
|
81
|
+
expect(dataUri?.startsWith('diff')).toBeTruthy();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import { expect } from '@playwright/test';
|
|
4
|
+
|
|
5
|
+
import { OpenSumiApp } from '..';
|
|
6
|
+
import { OpenSumiDiffEditor } from '../diff-editor';
|
|
7
|
+
import { OpenSumiExplorerView } from '../explorer-view';
|
|
8
|
+
import { OpenSumiSearchView } from '../search-view';
|
|
9
|
+
import { OpenSumiTextEditor } from '../text-editor';
|
|
10
|
+
import { keypressWithCmdCtrlAndShift } from '../utils/key';
|
|
11
|
+
import { OpenSumiWorkspace } from '../workspace';
|
|
12
|
+
|
|
13
|
+
import test, { page } from './hooks';
|
|
14
|
+
|
|
15
|
+
let app: OpenSumiApp;
|
|
16
|
+
let search: OpenSumiSearchView;
|
|
17
|
+
let editor: OpenSumiTextEditor;
|
|
18
|
+
let explorer: OpenSumiExplorerView;
|
|
19
|
+
let workspace: OpenSumiWorkspace;
|
|
20
|
+
|
|
21
|
+
test.describe('OpenSumi Search Panel', () => {
|
|
22
|
+
test.beforeAll(async () => {
|
|
23
|
+
workspace = new OpenSumiWorkspace([path.resolve('./src/tests/workspaces/search')]);
|
|
24
|
+
app = await OpenSumiApp.load(page, workspace);
|
|
25
|
+
search = await app.open(OpenSumiSearchView);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('Can search files by simple text', async () => {
|
|
29
|
+
const searchText = 'hello';
|
|
30
|
+
expect(await search.isVisible()).toBeTruthy();
|
|
31
|
+
await search.search({
|
|
32
|
+
search: searchText,
|
|
33
|
+
});
|
|
34
|
+
await app.page.waitForTimeout(1000);
|
|
35
|
+
const result = await search.getSearchResult();
|
|
36
|
+
expect(result).toBeDefined();
|
|
37
|
+
if (result) {
|
|
38
|
+
const { results, files } = result;
|
|
39
|
+
expect(results).toBe(1);
|
|
40
|
+
expect(files).toBe(1);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('Open file with editor', async () => {
|
|
45
|
+
const searchText = 'hello';
|
|
46
|
+
expect(await search.isVisible()).toBeTruthy();
|
|
47
|
+
await search.search({
|
|
48
|
+
search: searchText,
|
|
49
|
+
});
|
|
50
|
+
await app.page.waitForTimeout(1000);
|
|
51
|
+
const result = await search.getSearchResult();
|
|
52
|
+
expect(result).toBeDefined();
|
|
53
|
+
if (result) {
|
|
54
|
+
const { results, files } = result;
|
|
55
|
+
expect(results).toBe(1);
|
|
56
|
+
expect(files).toBe(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const fileNode = await search.getTreeNodeByIndex(0);
|
|
60
|
+
const contentNode = await search.getTreeNodeByIndex(1);
|
|
61
|
+
|
|
62
|
+
expect(await fileNode?.isFile()).toBeTruthy();
|
|
63
|
+
expect(await contentNode?.isFile()).toBeFalsy();
|
|
64
|
+
|
|
65
|
+
expect(contentNode).toBeDefined();
|
|
66
|
+
if (contentNode) {
|
|
67
|
+
await contentNode?.open();
|
|
68
|
+
await app.page.waitForTimeout(1000);
|
|
69
|
+
|
|
70
|
+
const editor = new OpenSumiTextEditor(app, contentNode);
|
|
71
|
+
const currentTab = await editor.getCurrentTab();
|
|
72
|
+
const dataUri = await currentTab?.getAttribute('data-uri');
|
|
73
|
+
expect(dataUri?.startsWith('file')).toBeTruthy();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('Open file with diffEditor', async () => {
|
|
78
|
+
const searchText = 'hello';
|
|
79
|
+
const replaceText = 'Hello';
|
|
80
|
+
expect(await search.isVisible()).toBeTruthy();
|
|
81
|
+
await search.search({
|
|
82
|
+
search: searchText,
|
|
83
|
+
});
|
|
84
|
+
const input = await search.focusOnReplace();
|
|
85
|
+
await page.keyboard.type(replaceText);
|
|
86
|
+
|
|
87
|
+
const contentNode = await search.getTreeNodeByIndex(1);
|
|
88
|
+
expect(contentNode).toBeDefined();
|
|
89
|
+
if (contentNode) {
|
|
90
|
+
await contentNode.open();
|
|
91
|
+
await app.page.waitForTimeout(1000);
|
|
92
|
+
const editor = new OpenSumiDiffEditor(app, contentNode);
|
|
93
|
+
const currentTab = await editor.getCurrentTab();
|
|
94
|
+
const dataUri = await currentTab?.getAttribute('data-uri');
|
|
95
|
+
expect(dataUri?.startsWith('file')).toBeFalsy();
|
|
96
|
+
}
|
|
97
|
+
await input?.fill('');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('Open search rules view', async () => {
|
|
101
|
+
expect(await search.isVisible()).toBeTruthy();
|
|
102
|
+
await search.toggleDisplaySearchRules();
|
|
103
|
+
// Include input and Exclude input should be shown.
|
|
104
|
+
expect((await search.getIncludeInput())?.isVisible()).toBeTruthy();
|
|
105
|
+
expect((await search.getExcludeInput())?.isVisible()).toBeTruthy();
|
|
106
|
+
await search.toggleDisplaySearchRules();
|
|
107
|
+
expect((await search.getIncludeInput())?.isVisible()).toBeFalsy();
|
|
108
|
+
expect((await search.getExcludeInput())?.isVisible()).toBeFalsy();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('Replace search result with RegExp', async () => {
|
|
112
|
+
const searchText = 'const (.+) = require((.*))';
|
|
113
|
+
const replaceText = '$1...$2';
|
|
114
|
+
|
|
115
|
+
await search.search({
|
|
116
|
+
search: searchText,
|
|
117
|
+
useRegexp: true,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await app.page.waitForTimeout(1000);
|
|
121
|
+
let result = await search.getSearchResult();
|
|
122
|
+
expect(result).toBeDefined();
|
|
123
|
+
if (result) {
|
|
124
|
+
const { results, files } = result;
|
|
125
|
+
expect(results).toBe(1);
|
|
126
|
+
expect(files).toBe(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const input = await search.focusOnReplace();
|
|
130
|
+
await page.keyboard.type(replaceText);
|
|
131
|
+
|
|
132
|
+
const replaceButton = await search.getReplaceAllButton();
|
|
133
|
+
|
|
134
|
+
expect(await replaceButton?.isEnabled()).toBeTruthy();
|
|
135
|
+
await replaceButton?.click();
|
|
136
|
+
const confirmed = await app.getDialogButton('Replace');
|
|
137
|
+
await confirmed?.click();
|
|
138
|
+
await app.page.waitForTimeout(1000);
|
|
139
|
+
|
|
140
|
+
await search.search({
|
|
141
|
+
search: "fs...('fs')",
|
|
142
|
+
useRegexp: false,
|
|
143
|
+
});
|
|
144
|
+
await app.page.waitForTimeout(1000);
|
|
145
|
+
result = await search.getSearchResult();
|
|
146
|
+
expect(result).toBeDefined();
|
|
147
|
+
if (result) {
|
|
148
|
+
const { results, files } = result;
|
|
149
|
+
expect(results).toBe(1);
|
|
150
|
+
expect(files).toBe(1);
|
|
151
|
+
}
|
|
152
|
+
await input?.fill('');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('Search content with MatchCase', async () => {
|
|
156
|
+
const searchText = 'abcd';
|
|
157
|
+
|
|
158
|
+
await search.search({
|
|
159
|
+
search: searchText,
|
|
160
|
+
isMatchCase: true,
|
|
161
|
+
});
|
|
162
|
+
await app.page.waitForTimeout(1000);
|
|
163
|
+
let result = await search.getSearchResult();
|
|
164
|
+
await app.page.waitForTimeout(1000);
|
|
165
|
+
|
|
166
|
+
expect(result.results).toBe(1);
|
|
167
|
+
expect(result.files).toBe(1);
|
|
168
|
+
|
|
169
|
+
await search.search({
|
|
170
|
+
search: searchText,
|
|
171
|
+
isMatchCase: false,
|
|
172
|
+
});
|
|
173
|
+
await app.page.waitForTimeout(1000);
|
|
174
|
+
|
|
175
|
+
result = await search.getSearchResult();
|
|
176
|
+
expect(result.results).toBe(2);
|
|
177
|
+
expect(result.files).toBe(1);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test('Search content with editor selection', async () => {
|
|
181
|
+
explorer = await app.open(OpenSumiExplorerView);
|
|
182
|
+
explorer.initFileTreeView(workspace.workspace.displayName);
|
|
183
|
+
editor = await app.openEditor(OpenSumiTextEditor, explorer, 'index.js');
|
|
184
|
+
await editor.selectLineContainingText('hello');
|
|
185
|
+
await app.page.keyboard.press(keypressWithCmdCtrlAndShift('KeyF'), { delay: 200 });
|
|
186
|
+
|
|
187
|
+
await app.page.waitForTimeout(1000);
|
|
188
|
+
const result = await search.getSearchResult();
|
|
189
|
+
expect(result).toBeDefined();
|
|
190
|
+
if (result) {
|
|
191
|
+
const { results, files } = result;
|
|
192
|
+
expect(results).toBe(1);
|
|
193
|
+
expect(files).toBe(1);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('File content can not be search after deleted', async () => {
|
|
198
|
+
const searchText = 'console.log';
|
|
199
|
+
await search.search({
|
|
200
|
+
search: searchText,
|
|
201
|
+
useRegexp: false,
|
|
202
|
+
});
|
|
203
|
+
await app.page.waitForTimeout(1000);
|
|
204
|
+
let result = await search.getSearchResult();
|
|
205
|
+
expect(result).toBeDefined();
|
|
206
|
+
if (result) {
|
|
207
|
+
const { results, files } = result;
|
|
208
|
+
expect(results).toBe(4);
|
|
209
|
+
expect(files).toBe(2);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Delete `index2.js` file
|
|
213
|
+
if (!(await explorer.isVisible())) {
|
|
214
|
+
await explorer.open();
|
|
215
|
+
}
|
|
216
|
+
const file = await explorer.getFileStatTreeNodeByPath('index2.js');
|
|
217
|
+
expect(file).toBeDefined();
|
|
218
|
+
const menu = await file?.openContextMenu();
|
|
219
|
+
const deleteMenu = await menu?.menuItemByName('Delete');
|
|
220
|
+
await deleteMenu?.click();
|
|
221
|
+
await app.page.waitForTimeout(200);
|
|
222
|
+
const confirmed = await app.getDialogButton('Move to trash');
|
|
223
|
+
await confirmed?.click();
|
|
224
|
+
await app.page.waitForTimeout(2000);
|
|
225
|
+
|
|
226
|
+
await search.search({
|
|
227
|
+
search: searchText,
|
|
228
|
+
useRegexp: false,
|
|
229
|
+
});
|
|
230
|
+
await app.page.waitForTimeout(1000);
|
|
231
|
+
result = await search.getSearchResult();
|
|
232
|
+
expect(result).toBeDefined();
|
|
233
|
+
if (result) {
|
|
234
|
+
const { results, files } = result;
|
|
235
|
+
expect(results).toBe(3);
|
|
236
|
+
expect(files).toBe(1);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import { expect } from '@playwright/test';
|
|
4
|
+
|
|
5
|
+
import { OpenSumiApp } from '../app';
|
|
6
|
+
import { OpenSumiComponentEditor } from '../component-editor';
|
|
7
|
+
import { OPENSUMI_VIEW_CONTAINERS } from '../constans';
|
|
8
|
+
import { OpenSumiContextMenu } from '../context-menu';
|
|
9
|
+
import { OpenSumiExplorerView } from '../explorer-view';
|
|
10
|
+
import { keypressWithCmdCtrl } from '../utils';
|
|
11
|
+
import { OpenSumiWorkspace } from '../workspace';
|
|
12
|
+
|
|
13
|
+
import test, { page } from './hooks';
|
|
14
|
+
|
|
15
|
+
let app: OpenSumiApp;
|
|
16
|
+
let explorer: OpenSumiExplorerView;
|
|
17
|
+
let workspace: OpenSumiWorkspace;
|
|
18
|
+
|
|
19
|
+
test.describe('OpenSumi Shortcuts', () => {
|
|
20
|
+
test.beforeAll(async () => {
|
|
21
|
+
workspace = new OpenSumiWorkspace([path.resolve('./src/tests/workspaces/default')]);
|
|
22
|
+
app = await OpenSumiApp.load(page, workspace);
|
|
23
|
+
explorer = await app.open(OpenSumiExplorerView);
|
|
24
|
+
explorer.initFileTreeView(workspace.workspace.displayName);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test.afterAll(() => {
|
|
28
|
+
app.dispose();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const openSettingsView = async () => {
|
|
32
|
+
const leftTabbar = await app.page.waitForSelector(`#${OPENSUMI_VIEW_CONTAINERS.LEFT_TABBAR}`);
|
|
33
|
+
const settingsButton = await leftTabbar.$('[class*="titleActions___"] span');
|
|
34
|
+
await settingsButton?.click();
|
|
35
|
+
const menu = new OpenSumiContextMenu(app);
|
|
36
|
+
await menu.clickMenuItem('Settings');
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
test('open Settings by keybinding', async () => {
|
|
40
|
+
await explorer.fileTreeView.focus();
|
|
41
|
+
await app.page.keyboard.press(keypressWithCmdCtrl(','), { delay: 200 });
|
|
42
|
+
const editor = await app.openComponentEditor(
|
|
43
|
+
OpenSumiComponentEditor,
|
|
44
|
+
'pref:/',
|
|
45
|
+
'Settings',
|
|
46
|
+
"[class*='preferences___']",
|
|
47
|
+
);
|
|
48
|
+
expect(await editor.isVisible()).toBeTruthy();
|
|
49
|
+
await editor.close();
|
|
50
|
+
await app.page.waitForTimeout(1000);
|
|
51
|
+
expect(await editor.isVisible()).toBeFalsy();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('open Settings by settings button', async () => {
|
|
55
|
+
await openSettingsView();
|
|
56
|
+
const editor = await app.openComponentEditor(
|
|
57
|
+
OpenSumiComponentEditor,
|
|
58
|
+
'pref:/',
|
|
59
|
+
'Settings',
|
|
60
|
+
"[class*='preferences___']",
|
|
61
|
+
);
|
|
62
|
+
expect(await editor.isVisible()).toBeTruthy();
|
|
63
|
+
await editor.close();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('edit settings in settings.json', async () => {
|
|
67
|
+
await openSettingsView();
|
|
68
|
+
const editor = await app.openComponentEditor(
|
|
69
|
+
OpenSumiComponentEditor,
|
|
70
|
+
'pref:/',
|
|
71
|
+
'Settings',
|
|
72
|
+
"[class*='preferences___']",
|
|
73
|
+
);
|
|
74
|
+
expect(await editor.isVisible()).toBeTruthy();
|
|
75
|
+
const editorContainer = await editor.getContainer();
|
|
76
|
+
// Settings => View => Search => Search > Include
|
|
77
|
+
const tabs = (await editorContainer?.$$('[class*="group_item__"]')) || [];
|
|
78
|
+
let viewTab;
|
|
79
|
+
for (const tab of tabs) {
|
|
80
|
+
const title = await tab.textContent();
|
|
81
|
+
if (title === 'View') {
|
|
82
|
+
viewTab = tab;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
await viewTab.click();
|
|
87
|
+
await app.page.waitForTimeout(50);
|
|
88
|
+
const subTabs = (await editorContainer?.$$('[class*="index_item__"]')) || [];
|
|
89
|
+
let searchSetting;
|
|
90
|
+
for (const tab of subTabs) {
|
|
91
|
+
const title = await tab.textContent();
|
|
92
|
+
if (title === 'Search') {
|
|
93
|
+
searchSetting = tab;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
await searchSetting.click();
|
|
98
|
+
await app.page.waitForTimeout(1000);
|
|
99
|
+
const items = (await editorContainer?.$$('[class*="preference_item___"]')) || [];
|
|
100
|
+
let searchIncludeItem;
|
|
101
|
+
for (const item of items) {
|
|
102
|
+
const key = await (await item.$('[class*="key___"]'))?.textContent();
|
|
103
|
+
if (key?.trim() === 'Search > Include') {
|
|
104
|
+
searchIncludeItem = item;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const editButton = await searchIncludeItem.$('[class*="control_wrap___"] a');
|
|
109
|
+
expect(editButton).toBeDefined();
|
|
110
|
+
await editButton.click();
|
|
111
|
+
await app.page.waitForTimeout(2000);
|
|
112
|
+
const currentTab = await editor.getCurrentTab();
|
|
113
|
+
expect(await currentTab?.textContent()).toBe(' settings.json');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
// 使用 IntelliSense 了解相关属性。
|
|
3
|
+
// 悬停以查看现有属性的描述。
|
|
4
|
+
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Launch Program",
|
|
11
|
+
"program": "${workspaceFolder}/index.js",
|
|
12
|
+
"skipFiles": ["<node_internals>/**"]
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const str = 'hello';
|
|
2
|
+
const str2 = 'opensumi';
|
|
3
|
+
const buffStr = Buffer.from(str + str2);
|
|
4
|
+
|
|
5
|
+
const fn = () => {
|
|
6
|
+
let a = 0;
|
|
7
|
+
setTimeout(() => {
|
|
8
|
+
a += 1;
|
|
9
|
+
console.log(a);
|
|
10
|
+
}, 10);
|
|
11
|
+
console.log(a);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
fn();
|
|
15
|
+
|
|
16
|
+
console.log(str);
|
|
17
|
+
console.log(str2);
|
|
18
|
+
console.log(buffStr);
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// ------------------------------
|
|
2
|
+
// ------------------------------
|
|
3
|
+
function Person(age) {
|
|
4
|
+
if (age) {
|
|
5
|
+
this.age = age;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
Person.prototype.getAge = function () {
|
|
9
|
+
return this.age;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// ------------------------------
|
|
13
|
+
// ------------------------------
|
|
14
|
+
function Person(age) {
|
|
15
|
+
if (age) {
|
|
16
|
+
this.age = age;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
Person.prototype.getAge = function () {
|
|
20
|
+
return this.age;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// ------------------------------
|
|
24
|
+
// ------------------------------
|
|
25
|
+
function Person(age) {
|
|
26
|
+
if (age) {
|
|
27
|
+
this.age = age;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
Person.prototype.getAge = function () {
|
|
31
|
+
return this.age;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// ------------------------------
|
|
35
|
+
// ------------------------------
|
|
36
|
+
function Person(age) {
|
|
37
|
+
if (age) {
|
|
38
|
+
this.age = age;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
Person.prototype.getAge = function () {
|
|
42
|
+
return this.age;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// ------------------------------
|
|
46
|
+
// ------------------------------And this is some long line. And this is some long line. And this is some long line. And this is some long line. And this is some long line.
|
|
47
|
+
function Person(age) {
|
|
48
|
+
if (age) {
|
|
49
|
+
this.age = age;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
Person.prototype.getAge = function () {
|
|
53
|
+
return this.age;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// ------------------------------
|
|
57
|
+
// ------------------------------
|
|
58
|
+
function Person(age) {
|
|
59
|
+
if (age) {
|
|
60
|
+
this.age = age;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
Person.prototype.getAge = function () {
|
|
64
|
+
return this.age;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// ------------------------------
|
|
68
|
+
// ------------------------------
|
|
69
|
+
function Person(age) {
|
|
70
|
+
if (age) {
|
|
71
|
+
this.age = age;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
Person.prototype.getAge = function () {
|
|
75
|
+
return this.age;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// ------------------------------
|
|
79
|
+
// ------------------------------
|
|
80
|
+
function Person(age) {
|
|
81
|
+
if (age) {
|
|
82
|
+
this.age = age;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
Person.prototype.getAge = function () {
|
|
86
|
+
return this.age;
|
|
87
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('hello ./test/test.js');
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('This file will be deleted');
|