@theia/cli 1.53.0-next.5 → 1.53.0-next.55

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/src/run-test.ts CHANGED
@@ -1,87 +1,87 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2020 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- /* eslint-disable @typescript-eslint/no-explicit-any */
18
-
19
- import * as net from 'net';
20
- import * as puppeteer from 'puppeteer-core';
21
- import newTestPage, { TestFileOptions } from './test-page';
22
-
23
- export interface TestOptions {
24
- start: () => Promise<net.AddressInfo>
25
- launch?: puppeteer.PuppeteerLaunchOptions
26
- files?: Partial<TestFileOptions>
27
- coverage?: boolean
28
- }
29
-
30
- export default async function runTest(options: TestOptions): Promise<void> {
31
- const { start, launch } = options;
32
- const exit = !(launch && launch.devtools);
33
-
34
- const testPage = await newTestPage({
35
- files: options.files,
36
- matchAppUrl: () => true, // all urls are application urls
37
- newPage: async () => {
38
- const browser = await puppeteer.launch(launch);
39
- // re-use empty tab
40
- const [tab] = await browser.pages();
41
- return tab;
42
- },
43
- onWillRun: async () => {
44
- const promises = [];
45
- if (options.coverage) {
46
- promises.push(testPage.coverage.startJSCoverage());
47
- promises.push(testPage.coverage.startCSSCoverage());
48
- }
49
- // When launching in non-headless mode (with a UI and dev-tools open), make sure
50
- // the app has focus, to avoid failures of tests that query the UI's state.
51
- if (launch && launch.devtools) {
52
- promises.push(testPage.waitForSelector('#theia-app-shell.p-Widget.theia-ApplicationShell')
53
- .then(e => {
54
- // eslint-disable-next-line no-null/no-null
55
- if (e !== null) {
56
- e.click();
57
- }
58
- }));
59
- }
60
-
61
- // Clear application's local storage to avoid reusing previous state
62
- promises.push(testPage.evaluate(() => localStorage.clear()));
63
- await Promise.all(promises);
64
- },
65
- onDidRun: async failures => {
66
- if (options.coverage) {
67
- console.log('collecting test coverage...');
68
- const [jsCoverage, cssCoverage] = await Promise.all([
69
- testPage.coverage.stopJSCoverage(),
70
- testPage.coverage.stopCSSCoverage(),
71
- ]);
72
- require('puppeteer-to-istanbul').write([...jsCoverage, ...cssCoverage]);
73
- }
74
- if (exit) {
75
- // allow a bit of time to finish printing-out test results
76
- await new Promise(resolve => setTimeout(resolve, 1000));
77
- await testPage.close();
78
- process.exit(failures > 0 ? 1 : 0);
79
- }
80
- }
81
- });
82
- const { address, port } = await start();
83
- const url = net.isIPv6(address)
84
- ? `http://[${address}]:${port}`
85
- : `http://${address}:${port}`;
86
- await testPage.goto(url);
87
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2020 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+
19
+ import * as net from 'net';
20
+ import * as puppeteer from 'puppeteer-core';
21
+ import newTestPage, { TestFileOptions } from './test-page';
22
+
23
+ export interface TestOptions {
24
+ start: () => Promise<net.AddressInfo>
25
+ launch?: puppeteer.PuppeteerLaunchOptions
26
+ files?: Partial<TestFileOptions>
27
+ coverage?: boolean
28
+ }
29
+
30
+ export default async function runTest(options: TestOptions): Promise<void> {
31
+ const { start, launch } = options;
32
+ const exit = !(launch && launch.devtools);
33
+
34
+ const testPage = await newTestPage({
35
+ files: options.files,
36
+ matchAppUrl: () => true, // all urls are application urls
37
+ newPage: async () => {
38
+ const browser = await puppeteer.launch(launch);
39
+ // re-use empty tab
40
+ const [tab] = await browser.pages();
41
+ return tab;
42
+ },
43
+ onWillRun: async () => {
44
+ const promises = [];
45
+ if (options.coverage) {
46
+ promises.push(testPage.coverage.startJSCoverage());
47
+ promises.push(testPage.coverage.startCSSCoverage());
48
+ }
49
+ // When launching in non-headless mode (with a UI and dev-tools open), make sure
50
+ // the app has focus, to avoid failures of tests that query the UI's state.
51
+ if (launch && launch.devtools) {
52
+ promises.push(testPage.waitForSelector('#theia-app-shell.p-Widget.theia-ApplicationShell')
53
+ .then(e => {
54
+ // eslint-disable-next-line no-null/no-null
55
+ if (e !== null) {
56
+ e.click();
57
+ }
58
+ }));
59
+ }
60
+
61
+ // Clear application's local storage to avoid reusing previous state
62
+ promises.push(testPage.evaluate(() => localStorage.clear()));
63
+ await Promise.all(promises);
64
+ },
65
+ onDidRun: async failures => {
66
+ if (options.coverage) {
67
+ console.log('collecting test coverage...');
68
+ const [jsCoverage, cssCoverage] = await Promise.all([
69
+ testPage.coverage.stopJSCoverage(),
70
+ testPage.coverage.stopCSSCoverage(),
71
+ ]);
72
+ require('puppeteer-to-istanbul').write([...jsCoverage, ...cssCoverage]);
73
+ }
74
+ if (exit) {
75
+ // allow a bit of time to finish printing-out test results
76
+ await new Promise(resolve => setTimeout(resolve, 1000));
77
+ await testPage.close();
78
+ process.exit(failures > 0 ? 1 : 0);
79
+ }
80
+ }
81
+ });
82
+ const { address, port } = await start();
83
+ const url = net.isIPv6(address)
84
+ ? `http://[${address}]:${port}`
85
+ : `http://${address}:${port}`;
86
+ await testPage.goto(url);
87
+ }
package/src/test-page.ts CHANGED
@@ -1,138 +1,138 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2020 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- /* eslint-disable @typescript-eslint/no-explicit-any */
18
-
19
- import * as puppeteer from 'puppeteer-core';
20
- const collectFiles: (options: TestFileOptions) => string[] = require('mocha/lib/cli/collect-files');
21
-
22
- export interface TestFileOptions {
23
- ignore: string[]
24
- extension: string[]
25
- file: string[]
26
- recursive: boolean
27
- sort: boolean
28
- spec: string[]
29
- }
30
-
31
- export interface TestPageOptions {
32
- files?: Partial<TestFileOptions>
33
- newPage: () => Promise<puppeteer.Page>
34
- matchAppUrl?: (url: string) => boolean
35
- onWillRun?: () => Promise<void>
36
- onDidRun?: (failures: number) => Promise<void>
37
- }
38
-
39
- export default async function newTestPage(options: TestPageOptions): Promise<puppeteer.Page> {
40
- const { newPage, matchAppUrl, onWillRun, onDidRun } = options;
41
-
42
- const fileOptions: TestFileOptions = {
43
- ignore: options.files && options.files.ignore || [],
44
- extension: options.files && options.files.extension || [],
45
- file: options.files && options.files.file || [],
46
- spec: options.files && options.files.spec || [],
47
- recursive: options.files && options.files.recursive || false,
48
- sort: options.files && options.files.sort || false
49
- };
50
-
51
- // quick check whether test files exist
52
- const files = collectFiles(fileOptions);
53
-
54
- const page = await newPage();
55
- page.on('dialog', dialog => dialog.dismiss());
56
- page.on('pageerror', console.error);
57
-
58
- let theiaLoaded = false;
59
- page.exposeFunction('fireDidUnloadTheia', () => theiaLoaded = false);
60
- const preLoad = (frame: puppeteer.Frame) => {
61
- const frameUrl = frame.url();
62
- if (matchAppUrl && !matchAppUrl(frameUrl)) {
63
- return;
64
- }
65
- if (theiaLoaded) {
66
- return;
67
- }
68
- console.log('loading chai...');
69
- theiaLoaded = true;
70
- page.addScriptTag({ path: require.resolve('chai/chai.js') });
71
- page.evaluate(() =>
72
- window.addEventListener('beforeunload', () => (window as any)['fireDidUnloadTheia']())
73
- );
74
- };
75
- page.on('frameattached', preLoad);
76
- page.on('framenavigated', preLoad);
77
-
78
- page.on('load', async () => {
79
- if (matchAppUrl && !matchAppUrl(page.url())) {
80
- return;
81
- }
82
- console.log('loading mocha...');
83
- // replace console.log by theia logger for mocha
84
- await page.waitForFunction(() => !!(window as any)['theia']?.['@theia/core/lib/common/logger']?.logger, {
85
- timeout: 30 * 1000
86
- });
87
- await page.addScriptTag({ path: require.resolve('mocha/mocha.js') });
88
- await page.waitForFunction(() => !!(window as any)['chai'] && !!(window as any)['mocha'] && !!(window as any)['theia'].container, { timeout: 30 * 1000 });
89
-
90
- console.log('loading Theia...');
91
- await page.evaluate(() => {
92
- const { FrontendApplicationStateService } = (window as any)['theia']['@theia/core/lib/browser/frontend-application-state'];
93
- const { PreferenceService } = (window as any)['theia']['@theia/core/lib/browser/preferences/preference-service'];
94
- const { WorkspaceService } = (window as any)['theia']['@theia/workspace/lib/browser/workspace-service'];
95
-
96
- const container = (window as any)['theia'].container;
97
- const frontendApplicationState = container.get(FrontendApplicationStateService);
98
- const preferenceService = container.get(PreferenceService);
99
- const workspaceService = container.get(WorkspaceService);
100
-
101
- return Promise.all([
102
- frontendApplicationState.reachedState('ready'),
103
- preferenceService.ready,
104
- workspaceService.roots
105
- ]);
106
- });
107
-
108
- console.log('loading test files...');
109
- await page.evaluate(() => {
110
- // replace require to load modules from theia namespace
111
- (window as any)['require'] = (moduleName: string) => (window as any)['theia'][moduleName];
112
- mocha.setup({
113
- reporter: 'spec',
114
- ui: 'bdd',
115
- color: true,
116
- retries: 0,
117
- timeout: 10000
118
- });
119
- });
120
-
121
- if (onWillRun) {
122
- await onWillRun();
123
- }
124
-
125
- for (const file of files) {
126
- await page.addScriptTag({ path: file });
127
- }
128
-
129
- console.log('running test files...');
130
- const failures = await page.evaluate(() =>
131
- new Promise<number>(resolve => mocha.run(resolve))
132
- );
133
- if (onDidRun) {
134
- await onDidRun(failures);
135
- }
136
- });
137
- return page;
138
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2020 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+
19
+ import * as puppeteer from 'puppeteer-core';
20
+ const collectFiles: (options: TestFileOptions) => string[] = require('mocha/lib/cli/collect-files');
21
+
22
+ export interface TestFileOptions {
23
+ ignore: string[]
24
+ extension: string[]
25
+ file: string[]
26
+ recursive: boolean
27
+ sort: boolean
28
+ spec: string[]
29
+ }
30
+
31
+ export interface TestPageOptions {
32
+ files?: Partial<TestFileOptions>
33
+ newPage: () => Promise<puppeteer.Page>
34
+ matchAppUrl?: (url: string) => boolean
35
+ onWillRun?: () => Promise<void>
36
+ onDidRun?: (failures: number) => Promise<void>
37
+ }
38
+
39
+ export default async function newTestPage(options: TestPageOptions): Promise<puppeteer.Page> {
40
+ const { newPage, matchAppUrl, onWillRun, onDidRun } = options;
41
+
42
+ const fileOptions: TestFileOptions = {
43
+ ignore: options.files && options.files.ignore || [],
44
+ extension: options.files && options.files.extension || [],
45
+ file: options.files && options.files.file || [],
46
+ spec: options.files && options.files.spec || [],
47
+ recursive: options.files && options.files.recursive || false,
48
+ sort: options.files && options.files.sort || false
49
+ };
50
+
51
+ // quick check whether test files exist
52
+ const files = collectFiles(fileOptions);
53
+
54
+ const page = await newPage();
55
+ page.on('dialog', dialog => dialog.dismiss());
56
+ page.on('pageerror', console.error);
57
+
58
+ let theiaLoaded = false;
59
+ page.exposeFunction('fireDidUnloadTheia', () => theiaLoaded = false);
60
+ const preLoad = (frame: puppeteer.Frame) => {
61
+ const frameUrl = frame.url();
62
+ if (matchAppUrl && !matchAppUrl(frameUrl)) {
63
+ return;
64
+ }
65
+ if (theiaLoaded) {
66
+ return;
67
+ }
68
+ console.log('loading chai...');
69
+ theiaLoaded = true;
70
+ page.addScriptTag({ path: require.resolve('chai/chai.js') });
71
+ page.evaluate(() =>
72
+ window.addEventListener('beforeunload', () => (window as any)['fireDidUnloadTheia']())
73
+ );
74
+ };
75
+ page.on('frameattached', preLoad);
76
+ page.on('framenavigated', preLoad);
77
+
78
+ page.on('load', async () => {
79
+ if (matchAppUrl && !matchAppUrl(page.url())) {
80
+ return;
81
+ }
82
+ console.log('loading mocha...');
83
+ // replace console.log by theia logger for mocha
84
+ await page.waitForFunction(() => !!(window as any)['theia']?.['@theia/core/lib/common/logger']?.logger, {
85
+ timeout: 30 * 1000
86
+ });
87
+ await page.addScriptTag({ path: require.resolve('mocha/mocha.js') });
88
+ await page.waitForFunction(() => !!(window as any)['chai'] && !!(window as any)['mocha'] && !!(window as any)['theia'].container, { timeout: 30 * 1000 });
89
+
90
+ console.log('loading Theia...');
91
+ await page.evaluate(() => {
92
+ const { FrontendApplicationStateService } = (window as any)['theia']['@theia/core/lib/browser/frontend-application-state'];
93
+ const { PreferenceService } = (window as any)['theia']['@theia/core/lib/browser/preferences/preference-service'];
94
+ const { WorkspaceService } = (window as any)['theia']['@theia/workspace/lib/browser/workspace-service'];
95
+
96
+ const container = (window as any)['theia'].container;
97
+ const frontendApplicationState = container.get(FrontendApplicationStateService);
98
+ const preferenceService = container.get(PreferenceService);
99
+ const workspaceService = container.get(WorkspaceService);
100
+
101
+ return Promise.all([
102
+ frontendApplicationState.reachedState('ready'),
103
+ preferenceService.ready,
104
+ workspaceService.roots
105
+ ]);
106
+ });
107
+
108
+ console.log('loading test files...');
109
+ await page.evaluate(() => {
110
+ // replace require to load modules from theia namespace
111
+ (window as any)['require'] = (moduleName: string) => (window as any)['theia'][moduleName];
112
+ mocha.setup({
113
+ reporter: 'spec',
114
+ ui: 'bdd',
115
+ color: true,
116
+ retries: 0,
117
+ timeout: 10000
118
+ });
119
+ });
120
+
121
+ if (onWillRun) {
122
+ await onWillRun();
123
+ }
124
+
125
+ for (const file of files) {
126
+ await page.addScriptTag({ path: file });
127
+ }
128
+
129
+ console.log('running test files...');
130
+ const failures = await page.evaluate(() =>
131
+ new Promise<number>(resolve => mocha.run(resolve))
132
+ );
133
+ if (onDidRun) {
134
+ await onDidRun(failures);
135
+ }
136
+ });
137
+ return page;
138
+ }