-
Notifications
You must be signed in to change notification settings - Fork 28
Add e2e tests into CI #2002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add e2e tests into CI #2002
Changes from all commits
ebe6f65
5d0d9e9
18e8d4b
28cee39
3aa068c
f1856eb
2cc9dfc
764640b
a9bc755
2dcfe05
b917f84
86bbe58
f7a84a4
6a24e45
97eb9f2
2a58c65
adf3176
6010bf0
c508884
ecc9794
d604662
b244499
8706cc3
7e5cf62
b77a11a
1d2303b
5e965cf
edd489e
cf52e17
a87b8e1
01e59a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "step": 14, | ||
| "loss": 0.9596208930015564, | ||
| "acc": 0.7735 | ||
| } | ||
| "step": 14, | ||
| "loss": 0.9596208930015564, | ||
| "acc": 0.7735 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| *.vsix | ||
| .vscode-test | ||
| .wdio-vscode-service | ||
| screenshots | ||
| README.md | ||
| LICENSE | ||
| CHANGELOG.md | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { join } from 'path' | ||
| import { getProcessPlatform } from '../env' | ||
|
|
||
| export const getVenvBinPath = (cwd: string, envDir: string, name: string) => | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [F] This needs to be separated so we don't have to |
||
| getProcessPlatform() === 'win32' | ||
| ? join(cwd, envDir, 'Scripts', `${name}.exe`) | ||
| : join(cwd, envDir, 'bin', name) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,22 +3,27 @@ import { | |
| closeAllEditors, | ||
| dismissAllNotifications, | ||
| getDVCActivityBarIcon, | ||
| waitForDvcToFinish, | ||
| waitForViewContainerToLoad | ||
| } from './util' | ||
| import { ExperimentsWebview } from './pageObjects/experimentsWebview' | ||
| import { PlotsWebview } from './pageObjects/plotsWebview' | ||
| import { delay } from '../../util/time' | ||
|
|
||
| suite('DVC Extension For Visual Studio Code', () => { | ||
| before('should finish loading the extension', async () => { | ||
| before('should finish loading the extension', async function () { | ||
| this.timeout(240000) | ||
| await waitForViewContainerToLoad() | ||
| return dismissAllNotifications() | ||
| }) | ||
|
|
||
| // avoid killing any background process after experiments have finished run | ||
| after(() => delay(30000)) | ||
| after(function () { | ||
| this.timeout(60000) | ||
| return waitForDvcToFinish() | ||
| }) | ||
|
|
||
| afterEach(() => browser.switchToFrame(null)) | ||
| afterEach(function () { | ||
| return browser.switchToFrame(null) | ||
| }) | ||
|
|
||
| describe('Activity Bar', () => { | ||
| it('should show the DVC Icon', async () => { | ||
|
|
@@ -35,7 +40,7 @@ suite('DVC Extension For Visual Studio Code', () => { | |
|
|
||
| await workbench.executeCommand('DVC: Show Experiments') | ||
|
|
||
| await webview.open() | ||
| await webview.focus() | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [F] These seem like better names to me because the methods don't actually |
||
|
|
||
| await browser.waitUntil(async () => { | ||
| const table = await webview.table$ | ||
|
|
@@ -44,15 +49,15 @@ suite('DVC Extension For Visual Studio Code', () => { | |
|
|
||
| expect(await webview.table$$).toHaveLength(1) | ||
|
|
||
| await webview.close() | ||
| await webview.unfocus() | ||
| }) | ||
|
|
||
| it('should update with a new row for each checkpoint when an experiment is running', async () => { | ||
| const workbench = await browser.getWorkbench() | ||
| const epochs = 15 | ||
| await workbench.executeCommand('DVC: Reset and Run Experiment') | ||
|
|
||
| await webview.open() | ||
| await webview.focus() | ||
|
|
||
| await browser.waitUntil(() => webview.expandAllRows()) | ||
|
|
||
|
|
@@ -66,13 +71,19 @@ suite('DVC Extension For Visual Studio Code', () => { | |
| const currentRows = await webview.row$$ | ||
| return currentRows.length >= initialRows.length + epochs | ||
| }, | ||
| { timeout: 120000 } | ||
| { interval: 5000, timeout: 180000 } | ||
| ) | ||
|
|
||
| await webview.unfocus() | ||
| await waitForDvcToFinish() | ||
| await webview.focus() | ||
|
|
||
| const finalRows = await webview.row$$ | ||
|
|
||
| expect(finalRows.length).toStrictEqual(initialRows.length + epochs) | ||
| await webview.close() | ||
| await webview.unfocus() | ||
| await waitForDvcToFinish() | ||
| await workbench.executeCommand('Terminal: Kill All Terminals') | ||
| }).timeout(180000) | ||
| }) | ||
|
|
||
|
|
@@ -87,7 +98,9 @@ suite('DVC Extension For Visual Studio Code', () => { | |
| const workbench = await browser.getWorkbench() | ||
| await workbench.executeCommand('DVC: Show Plots') | ||
|
|
||
| await webview.open() | ||
| await waitForDvcToFinish() | ||
|
|
||
| await webview.focus() | ||
|
|
||
| await browser.waitUntil(async () => { | ||
| return (await webview.vegaVisualization$$.length) === 6 | ||
|
|
@@ -101,7 +114,7 @@ suite('DVC Extension For Visual Studio Code', () => { | |
| expect(plotNotEmpty).toBe(true) | ||
| } | ||
|
|
||
| await webview.close() | ||
| await webview.unfocus() | ||
| }) | ||
| }) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ export const experiments = { | |
| ...webview, | ||
| expandRowButton: 'button[title="Expand Row"]', | ||
| row: '[role=row]', | ||
| table: '[role=table]' | ||
| table: '[role=tree]' | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [F] This changed when we move up to v18 of React |
||
| } | ||
|
|
||
| export const plots = { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,11 @@ | ||
| import { ChainablePromiseArray, ElementArray } from 'webdriverio' | ||
| import { ViewControl } from 'wdio-vscode-service' | ||
|
|
||
| export const dismissAllNotifications = () => | ||
| browser.waitUntil(async () => { | ||
| const findProgressBars = (): ChainablePromiseArray<ElementArray> => | ||
| $$('.monaco-progress-container') | ||
|
|
||
| export const dismissAllNotifications = async (): Promise<void> => { | ||
| await browser.waitUntil(async () => { | ||
| const workbench = await browser.getWorkbench() | ||
| const notifications = await workbench.getNotifications() | ||
| for (const n of notifications) { | ||
|
|
@@ -10,6 +14,23 @@ export const dismissAllNotifications = () => | |
| const openNotifications = await workbench.getNotifications() | ||
| return openNotifications.length === 0 | ||
| }) | ||
| } | ||
|
|
||
| const dvcIsWorking = async (): Promise<boolean> => { | ||
| const workbench = await browser.getWorkbench() | ||
| const statusBar = workbench.getStatusBar() | ||
| const statusBarItems = await statusBar.getItems() | ||
| return statusBarItems.some( | ||
| statusBarItem => | ||
| statusBarItem.includes('loading~spin') && statusBarItem.includes('DVC') | ||
| ) | ||
| } | ||
|
|
||
| export const waitForDvcToFinish = async (): Promise<void> => { | ||
| await browser.waitUntil(async () => !(await dvcIsWorking()), { | ||
| timeout: 60000 | ||
| }) | ||
| } | ||
|
|
||
| export const getDVCActivityBarIcon = async (): Promise<ViewControl> => { | ||
| const workbench = await browser.getWorkbench() | ||
|
|
@@ -22,8 +43,8 @@ export const getDVCActivityBarIcon = async (): Promise<ViewControl> => { | |
| return activityBar.getViewControl('DVC') as Promise<ViewControl> | ||
| } | ||
|
|
||
| export const waitForViewContainerToLoad = async () => { | ||
| const initialProgressBars = await $$('.monaco-progress-container') | ||
| export const waitForViewContainerToLoad = async (): Promise<void> => { | ||
| const initialProgressBars = await findProgressBars() | ||
| await browser.waitUntil(async () => { | ||
| const dvcIcon = await getDVCActivityBarIcon() | ||
| if (!dvcIcon) { | ||
|
|
@@ -35,28 +56,42 @@ export const waitForViewContainerToLoad = async () => { | |
| return !!view | ||
| }) | ||
|
|
||
| return browser.waitUntil(async () => { | ||
| await browser.waitUntil(async () => { | ||
| const numberOfProgressBarsInContainer = 7 | ||
| const currentProgressBars = await $$('.monaco-progress-container') | ||
| const currentProgressBars = await findProgressBars() | ||
|
|
||
| if ( | ||
| return !( | ||
| currentProgressBars.length < | ||
| initialProgressBars.length + numberOfProgressBarsInContainer | ||
| ) { | ||
| return false | ||
| } | ||
| ) | ||
| }) | ||
|
|
||
| await waitForDvcToFinish() | ||
|
|
||
| for (const progress of currentProgressBars) { | ||
| if ((await progress.getAttribute('aria-hidden')) !== 'true') { | ||
| const workbench = await browser.getWorkbench() | ||
| await workbench.executeCommand('DVC: Pull') | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [F] In the CI we need to pull all of the DVC tracked data. This was a headache to get working. |
||
|
|
||
| await browser.waitUntil( | ||
| async () => { | ||
| if (await dvcIsWorking()) { | ||
| return false | ||
| } | ||
| } | ||
|
|
||
| return true | ||
| }) | ||
| const currentProgressBars = await findProgressBars() | ||
|
|
||
| for (const progress of currentProgressBars) { | ||
| if (await progress.isDisplayed()) { | ||
| return false | ||
| } | ||
| } | ||
|
|
||
| return true | ||
| }, | ||
| { timeout: 180000 } | ||
| ) | ||
| } | ||
|
|
||
| export const closeAllEditors = async () => { | ||
| export const closeAllEditors = async (): Promise<void> => { | ||
| const workbench = await browser.getWorkbench() | ||
| const editorView = workbench.getEditorView() | ||
| return editorView.closeAllEditors() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,30 @@ | ||
| import { join, resolve } from 'path' | ||
| import { mkdirp } from 'fs-extra' | ||
| import { Options } from '@wdio/types' | ||
| import { getVenvBinPath } from '../../python/path' | ||
| import { Logger } from '../../common/logger' | ||
|
|
||
| const screenshotDir = join(__dirname, 'screenshots') | ||
|
|
||
| export const config: Options.Testrunner = { | ||
| after: async function () { | ||
| await browser.switchToFrame(null) | ||
| await browser.switchToFrame(null) | ||
| }, | ||
| afterTest: async (test, __, { passed }) => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [F] This is close to what is provided in the example tests for the service. If I get time I will extend the way that we do timeouts to also take screenshots. |
||
| if (passed) { | ||
| return | ||
| } | ||
|
|
||
| Logger.log('Capturing screenshot for debugging') | ||
|
|
||
| await browser.saveScreenshot( | ||
| join(screenshotDir, `${test.parent} - ${test.title}.png`) | ||
| ) | ||
| }, | ||
| baseUrl: 'http://localhost', | ||
| before: async function () { | ||
| mkdirp(screenshotDir) | ||
| await browser.setWindowSize(1600, 1200) | ||
| }, | ||
| capabilities: [ | ||
|
|
@@ -17,6 +34,13 @@ export const config: Options.Testrunner = { | |
| // @ts-expect-error these caps are not typed in WebdriverIO | ||
| 'wdio:vscodeOptions': { | ||
| extensionPath: resolve(__dirname, '..', '..', '..'), | ||
| userSettings: { | ||
| 'dvc.pythonPath': getVenvBinPath( | ||
| resolve(__dirname, '..', '..', '..', '..', 'demo'), | ||
| '.env', | ||
| 'python' | ||
| ) | ||
| }, | ||
| verboseLogging: false, | ||
| workspacePath: resolve(__dirname, '..', '..', '..', '..', 'demo') | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[F] By removing the less valuable
macOS-latesttests we make get back more minutes than we expend running the E2E tests in the main workflow.