From c1b8f16798589003308f0ed876bb4905be22e21f Mon Sep 17 00:00:00 2001 From: Zacharias Fragkiadakis Date: Sat, 4 Jan 2025 19:33:06 +0200 Subject: [PATCH] refactor(e2e): clean up settings test suite - Sets "waitFor" timeout globally - Extracts some functions to helper files - Generally cleans up the test suite Signed-off-by: Zacharias Fragkiadakis --- test/e2e/helpers/actions.ts | 8 +++ test/e2e/helpers/assertions.ts | 29 +++++++--- test/e2e/specs/settings.spec.ts | 98 +++++++++++++-------------------- test/e2e/wdio.conf.ts | 2 +- 4 files changed, 69 insertions(+), 68 deletions(-) diff --git a/test/e2e/helpers/actions.ts b/test/e2e/helpers/actions.ts index 268978d7..01ba2589 100644 --- a/test/e2e/helpers/actions.ts +++ b/test/e2e/helpers/actions.ts @@ -1,4 +1,12 @@ import type { Workbench } from 'wdio-vscode-service' +import { Key } from 'webdriverio' + +export async function clearInput(input: WebdriverIO.Element) { + // Focus the input, sometimes clicking doesn't work + await input.setValue('') + await browser.keys([Key.Ctrl, 'a']) + await browser.keys(Key.Backspace) +} /** * Opens the Radicle view container in the sidebar, by clicking the radicle button in the diff --git a/test/e2e/helpers/assertions.ts b/test/e2e/helpers/assertions.ts index 4bca11fb..0f52e996 100644 --- a/test/e2e/helpers/assertions.ts +++ b/test/e2e/helpers/assertions.ts @@ -1,5 +1,25 @@ import { browser } from '@wdio/globals' -import type { Workbench } from 'wdio-vscode-service' +import type { OutputView, Workbench } from 'wdio-vscode-service' + +/** + * Asserts the output view contains the expected text. + */ +export async function expectOutputToContain(outputView: OutputView, expected: string) { + await browser.waitUntil( + async () => { + /** + * The text in the output console is split by newlines, which can be affected by the size + * of the window. To avoid this, we join the text into a single string. + */ + const joinedText = (await outputView.getText()).join('') + + return joinedText.includes(expected) + }, + { + timeoutMsg: `expected the output text to contain "${expected}"`, + }, + ) +} /** * Asserts that the CLI Commands and Patches sections are visible in the sidebar. This is @@ -23,11 +43,6 @@ export async function expectStandardSidebarViewsToBeVisible(workbench: Workbench return false } }, - { - timeoutMsg: 'expected the standard sidebar views to be visible', - // TODO: zac fine tune these (globally?) - timeout: 20000, - interval: 500, - }, + { timeoutMsg: 'expected the standard sidebar views to be visible' }, ) } diff --git a/test/e2e/specs/settings.spec.ts b/test/e2e/specs/settings.spec.ts index 07991a11..5e20a99d 100644 --- a/test/e2e/specs/settings.spec.ts +++ b/test/e2e/specs/settings.spec.ts @@ -4,10 +4,19 @@ import isEqual from 'lodash/isEqual' import { Key } from 'webdriverio' import { $ } from 'zx' import { getFirstWelcomeViewText } from '../helpers/queries' -import { expectStandardSidebarViewsToBeVisible } from '../helpers/assertions' -import { closeRadicleViewContainer, openRadicleViewContainer } from '../helpers/actions' +import { + expectOutputToContain, + expectStandardSidebarViewsToBeVisible, +} from '../helpers/assertions' +import { + clearInput, + closeRadicleViewContainer, + openRadicleViewContainer, +} from '../helpers/actions' import { nodeHomePath } from '../constants/config' +const tempNodeHomePath = `${nodeHomePath}.temp` + describe('Settings', () => { let workbench: Workbench let settings: SettingsEditor @@ -35,8 +44,7 @@ describe('Settings', () => { }) after(async () => { - const searchBox = await getSettingsSearchBox(settings) - await clearInput(searchBox) + await clearInput(await getSettingsSearchBox(settings)) }) afterEach(async () => { @@ -46,14 +54,12 @@ describe('Settings', () => { }) it('warns the user if the rad binary is not found', async () => { - await browser.pause(1000) await setTextSettingValue(pathToRadBinarySetting, '/tmp') await expectRadBinaryNotFoundToBeVisible(workbench) }) it('recognizes the rad binary when a valid path is specified', async () => { - const tempNodeHomePath = `${nodeHomePath}.temp` await $`cp -r ${nodeHomePath} ${tempNodeHomePath}` await setTextSettingValue(pathToRadBinarySetting, `/tmp`) @@ -70,8 +76,6 @@ describe('Settings', () => { // This functionality does not seem to work // eslint-disable-next-line max-len it.skip('recognizes if the directory is created *after* the setting is updated', async () => { - const tempNodeHomePath = `${nodeHomePath}.temp` - await setTextSettingValue(pathToRadBinarySetting, tempNodeHomePath) await expectRadBinaryNotFoundToBeVisible(workbench) @@ -80,13 +84,18 @@ describe('Settings', () => { await expectStandardSidebarViewsToBeVisible(workbench) - await clearTextSetting(pathToRadBinarySetting) - await $`rm -rf ${tempNodeHomePath}` }) }) - describe('VS Code, when updating the "Path to Radicle to Node Home" setting,', () => { + /** + * In Linux CI: + * - The extension is having issues resolving the correct node home directory (RAD_HOME). + * - Even when node home is set explicitly in the settings, the extension incorrectly reports it + * as non-authenticated. + */ + // eslint-disable-next-line max-len + describe('VS Code, when updating the "Path to Radicle to Node Home" setting, @skipLinuxCI', () => { let pathToNodeHomeSetting: Setting let outputView: OutputView @@ -101,56 +110,47 @@ describe('Settings', () => { }) after(async () => { - const searchBox = await getSettingsSearchBox(settings) - await clearInput(searchBox) + await clearInput(await getSettingsSearchBox(settings)) }) afterEach(async () => { await outputView.clearText() await clearTextSetting(pathToNodeHomeSetting) - await expectOutputToContain(outputView, 'Using already unsealed Radicle identity') + await expectRadicleIdentityToBeFound(outputView) }) - /** - * In Linux CI: - * - The extension is having issues resolving the correct node home directory (RAD_HOME). - * - Even when set explicitly in the settings, the extension incorrectly reports it as - * non-authenticated. - */ - it('logs an error in the output console if the path is invalid @skipLinuxCI', async () => { + it('logs an error in the output console if the path is invalid', async () => { await outputView.clearText() await setTextSettingValue(pathToNodeHomeSetting, '/tmp') - await expectOutputToContain(outputView, '✗ Error: Radicle profile not found in') + await expectRadicleProfileNotToBeFound(outputView) }) - it('recognizes when a valid path is specified @skipLinuxCI', async () => { - const tempNodeHomePath = `${nodeHomePath}.temp` + it('recognizes when a valid path is specified', async () => { await $`cp -r ${nodeHomePath} ${tempNodeHomePath}` await outputView.clearText() await setTextSettingValue(pathToNodeHomeSetting, tempNodeHomePath) - await expectOutputToContain(outputView, 'Using already unsealed Radicle identity') + await expectRadicleIdentityToBeFound(outputView) await $`rm -rf ${tempNodeHomePath}` }) // This functionality does not seem to work // eslint-disable-next-line max-len - it.skip('recognizes if the directory is created *after* the setting is updated @skipLinuxCI', async () => { - const tempNodeHomePath = `${nodeHomePath}.temp` + it.skip('recognizes if the directory is created *after* the setting is updated', async () => { await outputView.clearText() await setTextSettingValue(pathToNodeHomeSetting, tempNodeHomePath) - await expectOutputToContain(outputView, '✗ Error: Radicle profile not found in') + await expectRadicleProfileNotToBeFound(outputView) await $`cp -r ${nodeHomePath} ${tempNodeHomePath}` - await expectOutputToContain(outputView, 'Using already unsealed Radicle identity') + await expectRadicleIdentityToBeFound(outputView) await $`rm -rf ${tempNodeHomePath}` }) @@ -162,8 +162,6 @@ async function expectRadBinaryNotFoundToBeVisible(workbench: Workbench) { async () => { const welcomeText = await getFirstWelcomeViewText(workbench) - console.log({ welcomeText }) - return isEqual(welcomeText, [ /* eslint-disable max-len */ 'Failed resolving the Radicle CLI binary.', @@ -172,15 +170,18 @@ async function expectRadBinaryNotFoundToBeVisible(workbench: Workbench) { /* eslint-enable max-len */ ]) }, - { - timeoutMsg: 'expected the rad binary not found message to be visible', - // TODO: zac fine tune these (globally?) - timeout: 20000, - interval: 500, - }, + { timeoutMsg: 'expected the rad binary not found message to be visible' }, ) } +async function expectRadicleIdentityToBeFound(outputView: OutputView) { + await expectOutputToContain(outputView, 'Using already unsealed Radicle identity') +} + +async function expectRadicleProfileNotToBeFound(outputView: OutputView) { + await expectOutputToContain(outputView, '✗ Error: Radicle profile not found in') +} + /** * Workaround to get the value of a `TextSetting`. * The `getValue` method of a `TextSetting` seems to be wrongly implemented and returns null. @@ -214,26 +215,3 @@ async function clearTextSetting(setting: Setting) { async function getSettingsSearchBox(settings: SettingsEditor) { return await settings.elem.$(settings.locatorMap.Editor['inputArea'] as string) } - -async function clearInput(input: WebdriverIO.Element) { - await input.setValue('') - await browser.keys([Key.Ctrl, 'a']) - await browser.keys(Key.Backspace) -} - -async function expectOutputToContain(outputView: OutputView, expected: string) { - await browser.waitUntil( - async () => { - /** - * The text in the output console is split by newlines, which can be affected by the size - * of the window. To avoid this, we join the text into a single string. - */ - const joinedText = (await outputView.getText()).join('') - - return joinedText.includes(expected) - }, - { - timeoutMsg: `expected the output text to contain "${expected}"`, - }, - ) -} diff --git a/test/e2e/wdio.conf.ts b/test/e2e/wdio.conf.ts index 93e36160..1d23a85f 100644 --- a/test/e2e/wdio.conf.ts +++ b/test/e2e/wdio.conf.ts @@ -56,7 +56,7 @@ export const config: Options.Testrunner = { }, ], logLevel: 'warn', - waitforTimeout: 10000, + waitforTimeout: 20000, services: [['vscode', { cachePath: path.join(rootDirPath, 'node_modules/.cache/wdio') }]], framework: 'mocha', reporters: ['spec'],