@theia/api-tests 1.34.2 → 1.36.0-next.21

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/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@theia/api-tests",
3
- "version": "1.34.2",
3
+ "version": "1.36.0-next.21+be025fcc0",
4
4
  "description": "Theia API tests",
5
5
  "dependencies": {
6
- "@theia/core": "1.34.2"
6
+ "@theia/core": "1.36.0-next.21+be025fcc0"
7
7
  },
8
8
  "license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0",
9
9
  "repository": {
@@ -20,5 +20,5 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
- "gitHead": "dba940bd8c0f9f4b324dad0e90d570d499456f60"
23
+ "gitHead": "be025fcc0dc20d3ee81bd882eac4d6c398093d33"
24
24
  }
@@ -16,6 +16,7 @@
16
16
 
17
17
  // @ts-check
18
18
  describe('animationFrame', function () {
19
+ this.timeout(5_000);
19
20
  const { assert } = chai;
20
21
  const { animationFrame } = require('@theia/core/lib/browser/browser');
21
22
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  // @ts-check
18
18
  describe('Find and Replace', function () {
19
-
19
+ this.timeout(5_000);
20
20
  const { assert } = chai;
21
21
 
22
22
  const { animationFrame } = require('@theia/core/lib/browser/browser');
@@ -29,7 +29,6 @@ describe('Find and Replace', function () {
29
29
  const { ContextKeyService } = require('@theia/core/lib/browser/context-key-service');
30
30
  const { FileNavigatorContribution } = require('@theia/navigator/lib/browser/navigator-contribution');
31
31
  const { ApplicationShell } = require('@theia/core/lib/browser/shell/application-shell');
32
-
33
32
  const container = window.theia.container;
34
33
  const editorManager = container.get(EditorManager);
35
34
  const workspaceService = container.get(WorkspaceService);
@@ -38,7 +37,6 @@ describe('Find and Replace', function () {
38
37
  const contextKeyService = container.get(ContextKeyService);
39
38
  const navigatorContribution = container.get(FileNavigatorContribution);
40
39
  const shell = container.get(ApplicationShell);
41
-
42
40
  const rootUri = workspaceService.tryGetRoots()[0].resource;
43
41
  const fileUri = rootUri.resolve('webpack.config.js');
44
42
 
@@ -59,18 +57,27 @@ describe('Find and Replace', function () {
59
57
  });
60
58
  }
61
59
 
60
+ function pause(ms = 500) {
61
+ console.debug(`pause test for: ${ms} ms`);
62
+ return new Promise(resolve => setTimeout(resolve, ms));
63
+ }
64
+
65
+
62
66
  before(() => {
63
67
  shell.leftPanelHandler.collapse();
64
68
  });
65
69
 
66
70
  beforeEach(async function () {
67
71
  await navigatorContribution.closeView();
72
+ await pause();
68
73
  await editorManager.closeAll({ save: false });
74
+ await pause();
69
75
  });
70
76
 
71
77
  afterEach(async () => {
72
78
  toTearDown.dispose();
73
79
  await navigatorContribution.closeView();
80
+ await pause();
74
81
  await editorManager.closeAll({ save: false });
75
82
  });
76
83
 
@@ -73,7 +73,7 @@ describe('Keybindings', function () {
73
73
  when: 'false'
74
74
  }));
75
75
 
76
- const editor = await editorManager.open(workspaceService.tryGetRoots()[0].resource.resolve('package.json'), {
76
+ const editor = await editorManager.open(workspaceService.tryGetRoots()[0].resource.resolve('webpack.config.js'), {
77
77
  mode: 'activate',
78
78
  selection: {
79
79
  start: {
@@ -83,7 +83,6 @@ describe('Keybindings', function () {
83
83
  }
84
84
  });
85
85
  toTearDown.push(editor);
86
-
87
86
  const waitForCommand = new Deferred();
88
87
  toTearDown.push(commands.onWillExecuteCommand(e => waitForCommand.resolve(e.commandId)));
89
88
  keybindings.dispatchKeyDown({
@@ -300,7 +300,7 @@ describe('Saveable', function () {
300
300
  try {
301
301
  await fileService.delete(fileUri);
302
302
  await waitForDidChangeTitle.promise;
303
- assert.isTrue(widget.title.label.endsWith('(deleted)'), 'should be marked as deleted');
303
+ assert.isTrue(widget.title.label.endsWith('(Deleted)'), 'should be marked as deleted');
304
304
  assert.isTrue(Saveable.isDirty(widget), 'should be dirty after delete');
305
305
  assert.isFalse(widget.isDisposed, 'model should NOT be disposed after delete');
306
306
  } finally {
@@ -474,7 +474,7 @@ describe('Saveable', function () {
474
474
  try {
475
475
  await fileService.delete(fileUri);
476
476
  await waitForDidChangeTitle.promise;
477
- assert.isTrue(widget.title.label.endsWith('(deleted)'));
477
+ assert.isTrue(widget.title.label.endsWith('(Deleted)'));
478
478
  assert.isFalse(widget.isDisposed);
479
479
  } finally {
480
480
  widget.title.changed.disconnect(listener);
@@ -58,6 +58,7 @@ describe('TypeScript', function () {
58
58
 
59
59
  const typescriptPluginId = 'vscode.typescript-language-features';
60
60
  const referencesPluginId = 'ms-vscode.references-view';
61
+ const eslintPluginId = 'dbaeumer.vscode-eslint';
61
62
  /** @type Uri.URI */
62
63
  const rootUri = workspaceService.tryGetRoots()[0].resource;
63
64
  const demoFileUri = rootUri.resolveToAbsolute('../api-tests/test-ts-workspace/demo-file.ts');
@@ -66,22 +67,25 @@ describe('TypeScript', function () {
66
67
 
67
68
  before(async function () {
68
69
  await pluginService.didStart;
69
- await Promise.all([typescriptPluginId, referencesPluginId].map(async pluginId => {
70
+ await Promise.all([typescriptPluginId, referencesPluginId, eslintPluginId].map(async pluginId => {
70
71
  if (!pluginService.getPlugin(pluginId)) {
71
72
  throw new Error(pluginId + ' should be started');
72
73
  }
73
74
  await pluginService.activatePlugin(pluginId);
74
75
  }).concat(preferences.set('files.autoSave', 'off', PreferenceScope.User)));
76
+ await preferences.set('files.refactoring.autoSave', 'off', PreferenceScope.User);
75
77
  });
76
78
 
77
79
  beforeEach(async function () {
78
80
  await editorManager.closeAll({ save: false });
81
+ await new Promise(resolve => setTimeout(resolve, 500));
79
82
  });
80
83
 
81
84
  const toTearDown = new DisposableCollection();
82
85
  afterEach(async () => {
83
86
  toTearDown.dispose();
84
87
  await editorManager.closeAll({ save: false });
88
+ await new Promise(resolve => setTimeout(resolve, 500));
85
89
  });
86
90
 
87
91
  after(async () => {
@@ -234,6 +238,13 @@ describe('TypeScript', function () {
234
238
  assert.equal(activeEditor.getControl().getModel().getWordAtPosition({ lineNumber, column }).word, 'constructor');
235
239
  });
236
240
 
241
+ // Note: this test generate annoying but apparently harmless error traces, during cleanup:
242
+ // [Error: Error: Cannot update an unmounted root.
243
+ // at ReactDOMRoot.__webpack_modules__.../../node_modules/react-dom/cjs/react-dom.development.js.ReactDOMHydrationRoot.render.ReactDOMRoot.render (http://127.0.0.1:3000/bundle.js:92757:11)
244
+ // at BreadcrumbsRenderer.render (http://127.0.0.1:3000/bundle.js:137316:23)
245
+ // at BreadcrumbsRenderer.update (http://127.0.0.1:3000/bundle.js:108722:14)
246
+ // at BreadcrumbsRenderer.refresh (http://127.0.0.1:3000/bundle.js:108719:14)
247
+ // at async ToolbarAwareTabBar.updateBreadcrumbs (http://127.0.0.1:3000/bundle.js:128229:9)]
237
248
  it(`from ${from} to another editor`, async function () {
238
249
  await editorManager.open(definitionFileUri, { mode: 'open' });
239
250
 
@@ -298,6 +309,13 @@ describe('TypeScript', function () {
298
309
  await closePeek(activeEditor);
299
310
  });
300
311
 
312
+ // Note: this test generate annoying but apparently harmless error traces, during cleanup:
313
+ // [Error: Error: Cannot update an unmounted root.
314
+ // at ReactDOMRoot.__webpack_modules__.../../node_modules/react-dom/cjs/react-dom.development.js.ReactDOMHydrationRoot.render.ReactDOMRoot.render (http://127.0.0.1:3000/bundle.js:92757:11)
315
+ // at BreadcrumbsRenderer.render (http://127.0.0.1:3000/bundle.js:137316:23)
316
+ // at BreadcrumbsRenderer.update (http://127.0.0.1:3000/bundle.js:108722:14)
317
+ // at BreadcrumbsRenderer.refresh (http://127.0.0.1:3000/bundle.js:108719:14)
318
+ // at async ToolbarAwareTabBar.updateBreadcrumbs (http://127.0.0.1:3000/bundle.js:128229:9)]
301
319
  it(`from ${from} to another editor`, async function () {
302
320
  await editorManager.open(definitionFileUri, { mode: 'open' });
303
321
 
@@ -346,7 +364,6 @@ describe('TypeScript', function () {
346
364
 
347
365
  it('editor.action.triggerSuggest', async function () {
348
366
  const editor = await openEditor(demoFileUri);
349
- // const demoVariable = demoInstance.[stringField];
350
367
  editor.getControl().setPosition({ lineNumber: 26, column: 46 });
351
368
  editor.getControl().setSelection(new Selection(26, 46, 26, 35));
352
369
  assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'stringField');
@@ -360,8 +377,17 @@ describe('TypeScript', function () {
360
377
  assert.isTrue(contextKeyService.match('editorTextFocus'));
361
378
  assert.isTrue(contextKeyService.match('suggestWidgetVisible'));
362
379
 
380
+ // May need a couple extra "Enter" being sent for the suggest to be accepted
363
381
  keybindings.dispatchKeyDown('Enter');
364
- await waitForAnimation(() => !contextKeyService.match('suggestWidgetVisible'));
382
+ await waitForAnimation(() => {
383
+ const suggestWidgetDismissed = !contextKeyService.match('suggestWidgetVisible');
384
+ if (!suggestWidgetDismissed) {
385
+ console.log('Re-try accepting suggest using "Enter" key');
386
+ keybindings.dispatchKeyDown('Enter');
387
+ return false;
388
+ }
389
+ return true;
390
+ }, 5000, 'Suggest widget has not been dismissed despite attempts to accept suggestion');
365
391
 
366
392
  assert.isTrue(contextKeyService.match('editorTextFocus'));
367
393
  assert.isFalse(contextKeyService.match('suggestWidgetVisible'));
@@ -410,7 +436,17 @@ describe('TypeScript', function () {
410
436
  assert.isTrue(contextKeyService.match('suggestWidgetVisible'));
411
437
 
412
438
  keybindings.dispatchKeyDown('Escape');
413
- await waitForAnimation(() => !contextKeyService.match('suggestWidgetVisible') && getFocusedLabel() === undefined, 5000);
439
+
440
+ // once in a while, a second "Escape" is needed to dismiss widget
441
+ await waitForAnimation(() => {
442
+ const suggestWidgetDismissed = !contextKeyService.match('suggestWidgetVisible') && getFocusedLabel() === undefined;
443
+ if (!suggestWidgetDismissed) {
444
+ console.log('Re-try to dismiss suggest using "Escape" key');
445
+ keybindings.dispatchKeyDown('Escape');
446
+ return false;
447
+ }
448
+ return true;
449
+ }, 5000, 'Suggest widget not dismissed');
414
450
 
415
451
  assert.isUndefined(getFocusedLabel());
416
452
  assert.isFalse(contextKeyService.match('suggestWidgetVisible'));
@@ -629,7 +665,6 @@ SPAN {
629
665
  const editor = await openEditor(demoFileUri);
630
666
  const currentChar = () => editor.getControl().getModel().getLineContent(lineNumber).charAt(column - 1);
631
667
 
632
- // const demoVariable = demoInstance.stringField; --> const demoVariable = demoInstance.stringFiel;
633
668
  editor.getControl().getModel().applyEdits([{
634
669
  range: {
635
670
  startLineNumber: lineNumber,
@@ -642,7 +677,7 @@ SPAN {
642
677
  }]);
643
678
  editor.getControl().setPosition({ lineNumber, column });
644
679
  editor.getControl().revealPosition({ lineNumber, column });
645
- assert.equal(currentChar(), ';');
680
+ assert.equal(currentChar(), ';', 'Failed at assert 1');
646
681
 
647
682
  /** @type {import('@theia/monaco-editor-core/src/vs/editor/contrib/codeAction/browser/codeActionCommands').CodeActionController} */
648
683
  const codeActionController = editor.getControl().getContribution('editor.contrib.codeActionController');
@@ -656,23 +691,41 @@ SPAN {
656
691
  return !!node && node.style.visibility !== 'hidden';
657
692
  };
658
693
 
659
- assert.isFalse(lightBulbVisible());
694
+ assert.isFalse(lightBulbVisible(), 'Failed at assert 2');
660
695
  await waitForAnimation(() => lightBulbVisible());
661
696
 
662
697
  await commands.executeCommand('editor.action.quickFix');
663
698
  const codeActionSelector = '.codeActionWidget';
664
- assert.isFalse(!!document.querySelector(codeActionSelector), 'codeActionWidget should not be visible');
665
-
666
- await waitForAnimation(() => !!document.querySelector(codeActionSelector), 5000);
699
+ assert.isFalse(!!document.querySelector(codeActionSelector), 'Failed at assert 3 - codeActionWidget should not be visible');
700
+
701
+ console.log('Waiting for Quick Fix widget to be visible');
702
+ await waitForAnimation(() => {
703
+ const quickFixWidgetVisible = !!document.querySelector(codeActionSelector);
704
+ if (!quickFixWidgetVisible) {
705
+ console.log('...');
706
+ return false;
707
+ }
708
+ return true;
709
+ }, 10000, 'Timed-out waiting for the QuickFix widget to appear');
667
710
  await animationFrame();
668
711
 
712
+ assert.isTrue(lightBulbVisible(), 'Failed at assert 4');
669
713
  keybindings.dispatchKeyDown('Enter');
714
+ console.log('Waiting for confirmation that QuickFix has taken effect');
715
+ await waitForAnimation(() => {
716
+ const quickFixHasTakenEffect = !lightBulbVisible();
717
+ if (!quickFixHasTakenEffect) {
718
+ console.log('...');
719
+ return false;
720
+ }
721
+ return true;
722
+ }, 5000, 'Quickfix widget has not been dismissed despite attempts to accept suggestion');
670
723
 
671
- await waitForAnimation(() => currentChar() === 'd', 5000);
672
- assert.equal(currentChar(), 'd');
724
+ await waitForAnimation(() => currentChar() === 'd', 5000, 'Failed to detect expected selected char: "d"');
725
+ assert.equal(currentChar(), 'd', 'Failed at assert 5');
673
726
 
674
727
  await waitForAnimation(() => !lightBulbVisible());
675
- assert.isFalse(lightBulbVisible());
728
+ assert.isFalse(lightBulbVisible(), 'Failed at assert 6');
676
729
  });
677
730
 
678
731
  it('editor.action.formatDocument', async function () {
@@ -722,16 +775,12 @@ SPAN {
722
775
  it(referenceViewCommand, async function () {
723
776
  let steps = 0;
724
777
  const editor = await openEditor(demoFileUri);
725
- // const demo|Instance = new DemoClass('demo');
726
778
  editor.getControl().setPosition({ lineNumber: 24, column: 11 });
727
779
  assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'demoInstance');
780
+ await commands.executeCommand(referenceViewCommand);
728
781
  const view = await pluginViewRegistry.openView('references-view.tree', { reveal: true });
729
- assert.isDefined(view);
730
- assert.isTrue(view.isVisible);
731
- await commands.executeCommand('references-view.clear');
732
782
  const expectedMessage = referenceViewCommand === 'references-view.find' ? '2 results in 1 file' : '1 result in 1 file';
733
783
  const getResultText = () => view.node.getElementsByClassName('theia-TreeViewInfo').item(0)?.textContent;
734
- await commands.executeCommand(referenceViewCommand);
735
784
  await waitForAnimation(() => getResultText() === expectedMessage, 5000);
736
785
  assert.equal(getResultText(), expectedMessage);
737
786
  });
@@ -746,7 +795,6 @@ SPAN {
746
795
  return lightbulbVisibility !== undefined && lightbulbVisibility !== 'hidden';
747
796
  }
748
797
  assert.isFalse(isActionAvailable());
749
- // import { DefinedInterface } from "./demo-definitions-file";
750
798
  assert.strictEqual(editor.getControl().getModel().getLineContent(30), 'import { DefinedInterface } from "./demo-definitions-file";');
751
799
  editor.getControl().revealLine(30);
752
800
  editor.getControl().setSelection(new Selection(30, 1, 30, 60));
@@ -764,16 +812,36 @@ SPAN {
764
812
  console.log(`content: ${editor.getControl().getModel().getLineContent(30)}`);
765
813
  await waitForAnimation(() => editor.getControl().getModel().getLineContent(30) === 'import * as demoDefinitionsFile from "./demo-definitions-file";', 5000, 'The namespace import did not take effect.');
766
814
 
815
+ // momentarily toggle selection, waiting for code action to become unavailable.
816
+ // Without doing this, the call to the quickfix command would sometimes fail because of an
817
+ // unexpected "no code action available" pop-up, which would trip the rest of the testcase
818
+ editor.getControl().setSelection(new Selection(30, 1, 30, 1));
819
+ console.log('waiting for code action to no longer be available');
820
+ await waitForAnimation(() => {
821
+ if (!isActionAvailable()) {
822
+ return true;
823
+ }
824
+ editor.getControl().setSelection(new Selection(30, 1, 30, 1));
825
+ console.log('...');
826
+ return !isActionAvailable();
827
+ }, 5000, 'Code action still available with no proper selection.');
828
+ // re-establish selection
767
829
  editor.getControl().setSelection(new Selection(30, 1, 30, 64));
768
- await waitForAnimation(() => isActionAvailable(), 5000, 'No code action available. (2)');
830
+ console.log('waiting for code action to become available again');
831
+ await waitForAnimation(() => {
832
+ console.log('...');
833
+ return isActionAvailable()
834
+ }, 5000, 'No code action available. (2)');
769
835
 
770
- // Change it back: https://github.com/eclipse-theia/theia/issues/11059
836
+ // Change import back: https://github.com/eclipse-theia/theia/issues/11059
771
837
  await commands.executeCommand('editor.action.quickFix');
772
838
  await waitForAnimation(() => Boolean(document.querySelector('.context-view-pointerBlock')), 5000, 'No context menu appeared. (2)');
773
839
  await animationFrame();
774
840
 
775
841
  keybindings.dispatchKeyDown('Enter');
776
842
 
843
+ assert.isNotNull(editor.getControl());
844
+ assert.isNotNull(editor.getControl().getModel());
777
845
  await waitForAnimation(() => editor.getControl().getModel().getLineContent(30) === 'import { DefinedInterface } from "./demo-definitions-file";', 5000, 'The named import did not take effect.');
778
846
  });
779
847
  });