diff --git a/test/smoke/src/areas/javascript.ts b/test/smoke/src/areas/javascript.ts index 86174b51658..e463be9dcda 100644 --- a/test/smoke/src/areas/javascript.ts +++ b/test/smoke/src/areas/javascript.ts @@ -5,10 +5,14 @@ import { SpectronApplication } from '../spectron/application'; +var htmlparser = require('htmlparser2'); + export class JavaScript { - private readonly appVarSelector = '.view-lines>:nth-child(7) .mtk11'; - private readonly firstCommentSelector = '.margin-view-overlays>:nth-child(3)'; - private readonly expressVarSelector = '.view-lines>:nth-child(11) .mtk10'; + private appVarSelector: string; + private expressVarSelector: string; + + private foldSelector: string; + private foldLine: number; constructor(private spectron: SpectronApplication) { // noop @@ -19,7 +23,13 @@ export class JavaScript { } public async findAppReferences(): Promise { - await this.spectron.client.click(this.appVarSelector, false); + await this.setAppVarSelector(); + try { + await this.spectron.client.click(this.appVarSelector, false); + } catch (e) { + return Promise.reject(`Failed to select 'app' variable.`); + } + return this.spectron.command('editor.action.referenceSearch.trigger'); } @@ -31,11 +41,18 @@ export class JavaScript { public async getTreeReferencesCount(): Promise { const treeElems = await this.spectron.client.elements('.reference-zone-widget.results-loaded .ref-tree.inline .show-twisties .monaco-tree-row'); + return treeElems.value.length; } public async renameApp(newValue: string): Promise { - await this.spectron.client.click(this.appVarSelector); + await this.setAppVarSelector(); + + try { + await this.spectron.client.click(this.appVarSelector); + } catch (e) { + return Promise.reject(`Failed to select 'app' variable.`); + } await this.spectron.command('editor.action.rename'); await this.spectron.wait(); return this.spectron.client.keys(newValue, false); @@ -46,28 +63,110 @@ export class JavaScript { } public async toggleFirstCommentFold(): Promise { - return this.spectron.client.click(`${this.firstCommentSelector} .cldr.folding`); + this.foldLine = await this.getLineIndexOfFirstFoldableElement(`.margin-view-overlays`); + this.foldSelector = `.margin-view-overlays>:nth-child(${this.foldLine})`; + + return this.spectron.client.click(`${this.foldSelector} .cldr.folding`); } public async getFirstCommentFoldedIcon(): Promise { - return this.spectron.client.getHTML(`${this.firstCommentSelector} .cldr.folding.collapsed`); + if (!this.foldSelector) { + return Promise.reject('No code folding happened to be able to check for a folded icon.'); + } + + return this.spectron.client.getHTML(`${this.foldSelector} .cldr.folding.collapsed`); } public async getNextLineNumberAfterFold(): Promise { - return this.spectron.client.getText(`.margin-view-overlays>:nth-child(4) .line-numbers`); + if (!this.foldLine) { + return Promise.reject('Folded line was not set, most likely because fold was not toggled initially.'); + } + + return this.spectron.client.getText(`.margin-view-overlays>:nth-child(${this.foldLine+1}) .line-numbers`); } public async goToExpressDefinition(): Promise { + await this.setExpressVarSelector(); await this.spectron.client.click(this.expressVarSelector); + return this.spectron.command('editor.action.goToDeclaration'); } public async peekExpressDefinition(): Promise { + await this.setExpressVarSelector(); await this.spectron.client.click(this.expressVarSelector); + return this.spectron.command('editor.action.previewDeclaration'); } public async getPeekExpressResultName(): Promise { return this.spectron.client.getText('.reference-zone-widget.results-loaded .filename'); } + + private async setAppVarSelector(): Promise { + if (!this.appVarSelector) { + const lineIndex = await this.getLineIndexOfFirst('app', '.view-lines'); + this.appVarSelector = `.view-lines>:nth-child(${lineIndex}) .mtk11`; + } + } + + private async setExpressVarSelector(): Promise { + if (!this.expressVarSelector) { + const lineIndex = await this.getLineIndexOfFirst('express', '.view-lines'); + this.expressVarSelector = `.view-lines>:nth-child(${lineIndex}) .mtk10`; + } + } + + private getLineIndexOfFirst(string: string, selector: string): Promise { + return new Promise(async (res, rej) => { + const html = await this.spectron.waitFor(this.spectron.client.getHTML, selector); + let lineIndex: number = 0; + let stringFound: boolean; + let parser = new htmlparser.Parser({ + onopentag: function (name: string, attribs: any) { + if (name === 'div' && attribs.class === 'view-line') { + lineIndex++; + } + }, + ontext: function (text) { + if (!stringFound && text === string) { + stringFound = true; + parser.end(); + } + }, + onend: function () { + if (!stringFound) { + return rej(`No ${string} in editor found.`); + } + return res(lineIndex); + } + }); + parser.write(html); + }); + } + + private getLineIndexOfFirstFoldableElement(selector: string): Promise { + return new Promise(async (res, rej) => { + const html = await this.spectron.waitFor(this.spectron.client.getHTML, selector); + let lineIndex: number = 0; + let foldFound: boolean; + let parser = new htmlparser.Parser({ + onopentag: function (name: string, attribs: any) { + if (name === 'div' && !attribs.class) { + lineIndex++; + } else if (name === 'div' && attribs.class.indexOf('cldr folding') !== -1) { + foldFound = true; + parser.end(); + } + }, + onend: function () { + if (!foldFound) { + return rej(`No foldable elements found.`); + } + return res(lineIndex); + } + }); + parser.write(html); + }); + } } \ No newline at end of file diff --git a/test/smoke/src/tests/javascript.ts b/test/smoke/src/tests/javascript.ts index 3bde32ccc39..2172bf56992 100644 --- a/test/smoke/src/tests/javascript.ts +++ b/test/smoke/src/tests/javascript.ts @@ -32,7 +32,7 @@ export function testJavaScript() { await js.openQuickOutline(); await app.wait(); const symbols = await common.getQuickOpenElements(); - assert.equal(symbols, 12); + assert.equal(symbols, 12, 'Quick outline elements count does not match to expected.'); }); it(`finds 'All References' to 'app'`, async function () { @@ -40,9 +40,9 @@ export function testJavaScript() { await js.findAppReferences(); await app.wait(); const titleCount = await js.getTitleReferencesCount(); - assert.equal(titleCount, 3); + assert.equal(titleCount, 3, 'References count in widget title is not as expected.'); const treeCount = await js.getTreeReferencesCount(); - assert.equal(treeCount, 3); + assert.equal(treeCount, 3, 'References count in tree is not as expected.'); }); it(`renames local 'app' variable`, async function () { @@ -60,13 +60,13 @@ export function testJavaScript() { // Fold await js.toggleFirstCommentFold(); const foldedIcon = await js.getFirstCommentFoldedIcon(); - assert.ok(foldedIcon); + assert.ok(foldedIcon, 'Folded icon was not found in the margin.'); let nextLineNumber = await js.getNextLineNumberAfterFold(); - assert.equal(nextLineNumber, 7); + assert.equal(nextLineNumber, 7, 'Line number after folded code is wrong.'); // Unfold await js.toggleFirstCommentFold(); nextLineNumber = await js.getNextLineNumberAfterFold(); - assert.equal(nextLineNumber, 4); + assert.equal(nextLineNumber, 4, 'Line number with unfolded code is wrong.'); }); it(`verifies that 'Go To Definition' works`, async function () {