Skip to content
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

e2e-test: browser in parallel & enable Currents #5442

Merged
merged 35 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
14eaa95
add currents
midleman Nov 21, 2024
b6d59cb
remove matrix
midleman Nov 26, 2024
0de5357
remove e2e-report
midleman Nov 26, 2024
41ba5e4
commit msg
midleman Nov 26, 2024
0a8eab4
try reporter
midleman Nov 26, 2024
ee3288a
oops
midleman Nov 26, 2024
d776001
commit msgs
midleman Nov 26, 2024
37ec510
ssh
midleman Nov 26, 2024
63d485e
update full
midleman Nov 26, 2024
4bb5317
shorten build id
midleman Nov 26, 2024
6fa7606
try 2 workers
midleman Nov 26, 2024
9556a15
unique ports
midleman Nov 26, 2024
0089933
Merge branch 'main' into mi/currents-ii
midleman Nov 26, 2024
3fe1f42
windows tag
midleman Nov 26, 2024
2146689
yolo 3 workers
midleman Nov 26, 2024
0fc4c87
tags
midleman Nov 26, 2024
96c2b37
echo commit msg
midleman Nov 26, 2024
41561f3
test release
midleman Nov 26, 2024
5d182b0
disable title tags
midleman Nov 26, 2024
71aa9fa
update tags
midleman Nov 26, 2024
e2957e1
release tags
midleman Nov 26, 2024
868bd8c
nit
midleman Nov 26, 2024
b6b7195
view file explorer
midleman Nov 27, 2024
bced409
some cleanup
midleman Nov 27, 2024
db3ea91
tweaks
midleman Nov 27, 2024
24158f7
missing comment
midleman Nov 27, 2024
71da822
fixture sshot
midleman Nov 27, 2024
7837234
add wait
midleman Nov 27, 2024
d4f2879
move env vars
midleman Nov 27, 2024
36921fd
nit
midleman Nov 27, 2024
3be58c5
move wait
midleman Nov 27, 2024
342f15a
slack on
midleman Nov 27, 2024
0fbb81d
improve loop
midleman Nov 27, 2024
edfb007
just refactor the whole thing
midleman Nov 27, 2024
93235bc
add comments for context
midleman Nov 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/e2e-test-release-run-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,15 @@ jobs:
env:
POSITRON_PY_VER_SEL: 3.10.12
POSITRON_R_VER_SEL: 4.4.0
id: electron-smoke-tests
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }}
PWTEST_BLOB_DO_NOT_REMOVE: 1
CURRENTS_TAG: "electron,release,${{ inputs.e2e_grep }}"
id: electron-e2e-tests
run: |
export DISPLAY=:10
BUILD=/usr/share/positron npx playwright test --project e2e-electron --workers 2 --grep="${{ env.E2E_GREP }}"
BUILD=/usr/share/positron npx playwright test --project e2e-electron --workers 3 --grep=${{ env.E2E_GREP }}

- name: Upload Playwright Report to S3
if: ${{ !cancelled() }}
Expand Down
27 changes: 17 additions & 10 deletions .github/workflows/positron-full-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ jobs:
e2e-electron-tests:
runs-on: ubuntu-latest-8x
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2]
shardTotal: [2]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
POSITRON_BUILD_NUMBER: 0 # CI skips building releases
Expand Down Expand Up @@ -131,26 +126,32 @@ jobs:
env:
POSITRON_PY_VER_SEL: 3.10.12
POSITRON_R_VER_SEL: 4.4.0
CURRENTS_PROJECT_ID: ZOs5z2
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }} # only works on push events
PWTEST_BLOB_DO_NOT_REMOVE: 1
CURRENTS_TAG: "electron"
id: electron-tests
run: DISPLAY=:10 npx playwright test --project e2e-electron --workers 1 --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
run: DISPLAY=:10 npx playwright test --project e2e-electron --workers 3

- name: Upload blob report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: blob-report-electron-${{ matrix.shardIndex }}
name: blob-report-electron
path: blob-report
retention-days: 14

- name: Upload junit report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: junit-report-electron-${{ matrix.shardIndex }}
name: junit-report-electron
path: test-results/junit.xml

e2e-browser-tests:
runs-on: ubuntu-latest-4x
runs-on: ubuntu-latest-8x
timeout-minutes: 50
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -188,8 +189,14 @@ jobs:
env:
POSITRON_PY_VER_SEL: 3.10.12
POSITRON_R_VER_SEL: 4.4.0
CURRENTS_PROJECT_ID: ZOs5z2
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }}
PWTEST_BLOB_DO_NOT_REMOVE: 1
CURRENTS_TAG: "chromium"
id: browser-tests
run: DISPLAY=:10 npx playwright test --project e2e-browser --workers 1
run: DISPLAY=:10 npx playwright test --project e2e-browser --workers 2

- name: Upload blob report
if: ${{ !cancelled() }}
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/positron-merge-to-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ jobs:
env:
POSITRON_PY_VER_SEL: 3.10.12
POSITRON_R_VER_SEL: 4.4.0
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }}
PWTEST_BLOB_DO_NOT_REMOVE: 1
CURRENTS_TAG: "electron,${{ inputs.e2e_grep }}"
id: e2e-playwright-tests
run: DISPLAY=:10 npx playwright test --project e2e-electron --workers 2 --grep="${{ env.E2E_GREP }}"
run: DISPLAY=:10 npx playwright test --project e2e-electron --workers 2 --grep=${{ env.E2E_GREP }}

- name: Upload Playwright Report to S3
if: ${{ success() || failure() }}
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/positron-windows-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,29 @@ jobs:
env:
POSITRON_PY_VER_SEL: 3.10.10
POSITRON_R_VER_SEL: 4.4.0
CURRENTS_PROJECT_ID: ZOs5z2
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }} # only works on push events
PWTEST_BLOB_DO_NOT_REMOVE: 1
CURRENTS_TAG: "electron,@win"
if: ${{ !cancelled() }}
id: e2e-win-electron-tests
run: npx playwright test --project e2e-electron --grep "@win" --workers 1
run: npx playwright test --project e2e-electron --grep "@win" --workers 2

- name: Upload blob report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: blob-report-electron-${{ matrix.shardIndex }}
name: blob-report-electron
path: blob-report
retention-days: 14

- name: Upload junit report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: junit-report-electron-${{ matrix.shardIndex }}
name: junit-report-electron
path: test-results/junit.xml

e2e-report:
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"update-localization-extension": "node build/npm/update-localization-extension.js",
"e2e": "yarn e2e-electron",
"e2e-electron": "npx playwright test --project e2e-electron",
"e2e-browser": "npx playwright test --project e2e-browser --workers 1",
"e2e-browser": "npx playwright test --project e2e-browser",
"e2e-pr": "npx playwright test --project e2e-electron --grep @pr",
"e2e-win": "npx playwright test --project e2e-electron --grep @win",
"e2e-failed": "npx playwright test --last-failed",
Expand Down Expand Up @@ -129,6 +129,7 @@
"yazl": "^2.4.3"
},
"devDependencies": {
"@currents/playwright": "^1.8.0",
"@midleman/github-actions-reporter": "^1.9.5",
"@playwright/test": "^1.49.0",
"@swc/core": "1.3.62",
Expand Down
9 changes: 8 additions & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { defineConfig } from '@playwright/test';
import { CustomTestOptions } from './test/smoke/src/areas/positron/_test.setup';
import type { GitHubActionOptions } from '@midleman/github-actions-reporter';
import { currentsReporter } from '@currents/playwright';

/**
* See https://playwright.dev/docs/test-configuration.
Expand Down Expand Up @@ -37,7 +38,13 @@ export default defineConfig<CustomTestOptions>({
includeResults: ['fail', 'flaky']
}],
['junit', { outputFile: 'test-results/junit.xml' }],
['list'], ['html'], ['blob']
['list'], ['html'], ['blob'],
currentsReporter({
ciBuildId: process.env.CURRENTS_CI_BUILD_ID || Date.now().toString(),
recordKey: process.env.CURRENTS_RECORD_KEY || '',
projectId: 'ZOs5z2',
disableTitleTags: true,
}),
]
: [
['list'],
Expand Down
115 changes: 77 additions & 38 deletions test/automation/src/playwrightBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,55 +42,94 @@ async function launchServer(options: LaunchOptions) {
...process.env
};

const args = [
'--disable-telemetry',
'--disable-workspace-trust',
`--port=${port++}`,
'--enable-smoke-test-driver',
`--extensions-dir=${extensionsPath}`,
`--server-data-dir=${agentFolder}`,
'--accept-server-license-terms',
`--logsPath=${serverLogsPath}`,
// --- Start Positron ---
`--connection-token`,
`dev-token`
// --- Start Positron ---
// Adding support for multiple ports to enable parallel test execution

let serverProcess: ChildProcess | null = null;
let endpoint: string | undefined;

const maxRetries = 10; // Number of ports to try before giving up
for (let attempts = 0; attempts < maxRetries; attempts++) {
const currentPort = port++; // Increment the port on each retry
// --- End Positron ---
];

if (options.verbose) {
args.push('--log=trace');
}
const args = [
'--disable-telemetry',
'--disable-workspace-trust',
// --- Start Positron ---
`--port=${currentPort}`,
// --- End Positron ---
'--enable-smoke-test-driver',
`--extensions-dir=${extensionsPath}`,
`--server-data-dir=${agentFolder}`,
'--accept-server-license-terms',
`--logsPath=${serverLogsPath}`,
// --- Start Positron ---
`--connection-token`,
`dev-token`
// --- End Positron ---
];

let serverLocation: string | undefined;
if (codeServerPath) {
const { serverApplicationName } = require(join(codeServerPath, 'product.json'));
serverLocation = join(codeServerPath, 'bin', `${serverApplicationName}${process.platform === 'win32' ? '.cmd' : ''}`);
if (options.verbose) {
args.push('--log=trace');
}

logger.log(`Starting built server from '${serverLocation}'`);
} else {
serverLocation = join(root, `scripts/code-server.${process.platform === 'win32' ? 'bat' : 'sh'}`);
let serverLocation: string | undefined;
if (codeServerPath) {
const { serverApplicationName } = require(join(codeServerPath, 'product.json'));
serverLocation = join(codeServerPath, 'bin', `${serverApplicationName}${process.platform === 'win32' ? '.cmd' : ''}`);

logger.log(`Starting server out of sources from '${serverLocation}'`);
}
logger.log(`Starting built server from '${serverLocation}'`);
} else {
serverLocation = join(root, `scripts/code-server.${process.platform === 'win32' ? 'bat' : 'sh'}`);

logger.log(`Storing log files into '${serverLogsPath}'`);
logger.log(`Starting server out of sources from '${serverLocation}'`);
}

logger.log(`Command line: '${serverLocation}' ${args.join(' ')}`);
const shell: boolean = (process.platform === 'win32');
const serverProcess = spawn(
serverLocation,
args,
{ env, shell }
);
logger.log(`Storing log files into '${serverLogsPath}'`);

logger.log(`Started server for browser smoke tests (pid: ${serverProcess.pid})`);
logger.log(`Command line: '${serverLocation}' ${args.join(' ')}`);
const shell: boolean = (process.platform === 'win32');

return {
serverProcess,
endpoint: await measureAndLog(() => waitForEndpoint(serverProcess, logger), 'waitForEndpoint(serverProcess)', logger)
};
// --- Start Positron ---
try {
serverProcess = spawn(
serverLocation,
args,
{ env, shell }
);

logger.log(`Started server on port ${currentPort} (pid: ${serverProcess.pid})`);

endpoint = await measureAndLog(
() => waitForEndpoint(serverProcess!, logger),
'waitForEndpoint(serverProcess)',
logger
);

// If we reach here, the server started successfully
break;
} catch (error) {
if ((error as Error).message.includes('EADDRINUSE')) {
logger.log(`Port ${currentPort} is already in use. Retrying with the next port...`);
if (serverProcess) {
serverProcess.kill();
}
} else {
throw error; // Rethrow non-EADDRINUSE errors
}
}
}

if (!serverProcess || !endpoint) {
throw new Error('Failed to launch the server after multiple attempts.');
}

return { serverProcess, endpoint };
// --- End Positron ---
}


async function launchBrowser(options: LaunchOptions, endpoint: string) {
const { logger, workspacePath, tracing, headless } = options;

Expand Down
2 changes: 1 addition & 1 deletion test/automation/src/positron/positronNotebooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class PositronNotebooks {
}

async assertCellOutput(text: string): Promise<void> {
await expect(this.frameLocator.getByText(text)).toBeVisible();
await expect(this.frameLocator.getByText(text)).toBeVisible({ timeout: 15000 });
}

async closeNotebookWithoutSaving() {
Expand Down
1 change: 0 additions & 1 deletion test/automation/src/positron/positronVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export class PositronVariables {
}

async doubleClickVariableRow(variableName: string) {

const desiredRow = await this.waitForVariableRow(variableName);
await desiredRow.dblclick();
}
Expand Down
45 changes: 35 additions & 10 deletions test/smoke/src/areas/positron/_test.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const TEMP_DIR = `temp-${randomUUID()}`;
const ROOT_PATH = process.cwd();
const LOGS_ROOT_PATH = join(ROOT_PATH, 'test-logs');
let SPEC_NAME = '';
let fixtureScreenshot: Buffer;

export const test = base.extend<TestFixtures, WorkerFixtures>({
suiteId: ['', { scope: 'worker', option: true }],
Expand Down Expand Up @@ -78,17 +79,33 @@ export const test = base.extend<TestFixtures, WorkerFixtures>({
await use(app);
}, { scope: 'test', timeout: 60000 }],

app: [async ({ options, logsPath, logger }, use) => {
app: [async ({ options, logsPath }, use, workerInfo) => {
const app = createApp(options);
await app.start();

await use(app);
try {
await app.start();

await use(app);
} catch (error) {
// capture a screenshot on failure
const screenshotPath = path.join(logsPath, 'app-start-failure.png');
try {
const page = app.code?.driver?.page;
if (page) {
fixtureScreenshot = await page.screenshot({ path: screenshotPath });
}
} catch {
// ignore
}

await app.stop();
throw error; // re-throw the error to ensure test failure
} finally {
await app.stop();

// rename the temp logs dir to the spec name
const specLogsPath = path.join(path.dirname(logsPath), SPEC_NAME);
await moveAndOverwrite(logsPath, specLogsPath);
// rename the temp logs dir to the spec name (if available)
const specLogsPath = path.join(path.dirname(logsPath), SPEC_NAME || `worker-${workerInfo.workerIndex}`);
await moveAndOverwrite(logsPath, specLogsPath);
}
}, { scope: 'worker', auto: true, timeout: 60000 }],

interpreter: [async ({ app, page }, use) => {
Expand Down Expand Up @@ -268,9 +285,17 @@ test.beforeAll(async ({ logger }, testInfo) => {
});

test.afterAll(async function ({ logger }, testInfo) {
logger.log('');
logger.log(`>>> Suite end: '${testInfo.titlePath[0] ?? 'unknown'}' <<<`);
logger.log('');
try {
logger.log('');
logger.log(`>>> Suite end: '${testInfo.titlePath[0] ?? 'unknown'}' <<<`);
logger.log('');
} catch (error) {
// ignore
}

if (fixtureScreenshot) {
await testInfo.attach('on-fixture-fail', { body: fixtureScreenshot, contentType: 'image/png' });
}
});

export { playwrightExpect as expect };
Expand Down
Loading