Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a4fab86
feat(a11y): add accessibility e2e test suite with baseline tests for …
walterra Jul 8, 2025
c926e2a
fix(a11y): update e2e test expectations to match current accessibilit…
walterra Jul 8, 2025
5c9854d
feat(e2e): add accessibility test suites for all chart types
walterra Jul 8, 2025
59de150
test(a11y): fix accessibility test assertions to include chart types
walterra Jul 8, 2025
31230ef
test(a11y): add comprehensive chart type coverage to accessibility tests
walterra Jul 8, 2025
ac8210f
test(a11y): update accessibility test expectations to match current o…
walterra Jul 8, 2025
4a91c3c
refactor(e2e): remove unused accessibility helper file
walterra Jul 8, 2025
287bc64
refactor(e2e): remove unused a11y helper and add edge case test comment
walterra Jul 8, 2025
e6e2581
refactor(e2e): consolidate accessibility test helper and unify test p…
walterra Jul 8, 2025
e7f9339
refactor(e2e): consolidate start scripts with --a11y flag
walterra Jul 9, 2025
8148d0e
refactor(e2e): consolidate test scripts by adding --a11y flag to test.sh
walterra Jul 9, 2025
c053de0
feat(ci): add accessibility e2e tests to Buildkite pipeline
walterra Jul 9, 2025
84dc582
feat(ci): add accessibility e2e tests to build pipeline
walterra Jul 9, 2025
9df31b9
refactor(e2e): move a11y tests to tests_a11y directory and update config
walterra Jul 9, 2025
7a57f62
fix(e2e): update a11y test imports and config for tests_a11y directory
walterra Jul 9, 2025
cccd3e8
fix(ci): use correct parallel key for a11y test job status reporting
walterra Jul 9, 2025
bbabde8
feat(ci): add A11Y report deployment and PR comment integration
walterra Jul 9, 2025
317af37
refactor(ci): improve code formatting in e2e reports script
walterra Jul 9, 2025
bbe6e4e
Merge branch 'main' into a11y-e2e-baseline
walterra Jul 18, 2025
5af5ad6
set parallelism to 1 for a11y e2e tests
walterra Jul 18, 2025
0dd4b46
skip flame chart a11y tests
walterra Jul 29, 2025
a63c147
more distinct naming related to VRT/A11Y e2e tests
walterra Jul 29, 2025
59f17fe
Merge branch 'main' into a11y-e2e-baseline
walterra Jul 29, 2025
c8ee7fb
add vrt postfix to playwright references
walterra Jul 31, 2025
011a06b
add more vrt references
walterra Jul 31, 2025
37b7e35
fix e2e->vrt
walterra Jul 31, 2025
18dad61
fix firebase deploy
walterra Jul 31, 2025
7c9cc4e
Merge branch 'main' into a11y-e2e-baseline
walterra Aug 8, 2025
f16bd3b
fix: review feedback
walterra Aug 8, 2025
0bdbc20
Merge branch 'main' into a11y-e2e-baseline
walterra Aug 11, 2025
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
6 changes: 4 additions & 2 deletions .buildkite/pipelines/pull_request/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
e2eServerStep,
eslintStep,
jestStep,
playwrightStep,
playwrightVrtStep,
playwrightA11yStep,
prettierStep,
docsStep,
storybookStep,
Expand Down Expand Up @@ -60,7 +61,8 @@ void (async () => {
e2eServerStep(),
firebasePreDeployStep(),
ghpDeployStep(),
playwrightStep(),
playwrightVrtStep(),
playwrightA11yStep(),
firebaseDeployStep(),
].map((step) => step(changeCtx));

Expand Down
2 changes: 1 addition & 1 deletion .buildkite/scripts/pre_exit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { yarnInstall } from './../utils/exec';
import { bkEnv, buildkiteGQLQuery, codeCheckIsCompleted, getJobMetadata, updateCheckStatus } from '../utils';

const skipChecks = new Set(['playwright']);
const skipChecks = new Set(['playwright_vrt', 'playwright_a11y']);

void (async function () {
const { checkId, jobId, jobUrl } = bkEnv;
Expand Down
24 changes: 17 additions & 7 deletions .buildkite/scripts/steps/e2e_reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ async function setGroupStatus() {
return;
}

const e2eJobs = await getBuildJobs('playwright__parallel-step');
const parallelKey =
checkId === 'playwright_a11y' ? 'playwright_a11y__parallel-step' : 'playwright_vrt__parallel-step';
const e2eJobs = await getBuildJobs(parallelKey);
const jobStateMap = new Map<string, number>();
jobStateMap.set('Success', 0);
jobStateMap.set('Failed', 0);
Expand Down Expand Up @@ -174,9 +176,17 @@ void (async () => {

await setGroupStatus();

await downloadArtifacts('.buildkite/artifacts/e2e_reports/*');
const { checkId } = bkEnv;
const isA11y = checkId === 'playwright_a11y';
const artifactPath = isA11y ? '.buildkite/artifacts/a11y_reports/*' : '.buildkite/artifacts/vrt_reports/*';
const reportDir = isA11y ? '.buildkite/artifacts/a11y_reports' : '.buildkite/artifacts/vrt_reports';
const outputDir = isA11y ? 'merged_a11y_html_report' : 'merged_vrt_html_report';
const outputArtifact = isA11y
? '.buildkite/artifacts/merged_a11y_html_report.gz'
: '.buildkite/artifacts/merged_vrt_html_report.gz';

await downloadArtifacts(artifactPath);

const reportDir = '.buildkite/artifacts/e2e_reports';
const files = fs.readdirSync(reportDir);
await Promise.all<void>(
files
Expand All @@ -189,18 +199,18 @@ void (async () => {
),
);

startGroup('Merging e2e reports');
startGroup(`Merging ${isA11y ? 'a11y' : 'e2e'} reports`);

await exec('yarn merge:reports', {
cwd: 'e2e',
env: {
HTML_REPORT_DIR: 'merged_html_report',
HTML_REPORT_DIR: outputDir,
},
});

await compress({
src: 'e2e/merged_html_report',
dest: '.buildkite/artifacts/merged_html_report.gz',
src: path.join('e2e', outputDir),
dest: outputArtifact,
});

if (bkEnv.steps.playwright.updateScreenshots) {
Expand Down
21 changes: 15 additions & 6 deletions .buildkite/scripts/steps/firebase_deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,33 @@ void (async () => {
dest: path.join(outDir, 'e2e'),
});

const e2eReportSrc = '.buildkite/artifacts/merged_html_report.gz';
await downloadArtifacts(e2eReportSrc, 'playwright_merge_and_status');
const vrtReportSrc = '.buildkite/artifacts/merged_vrt_html_report.gz';
await downloadArtifacts(vrtReportSrc, 'playwright_vrt_merge_and_status');
await decompress({
src: e2eReportSrc,
dest: path.join(outDir, 'e2e-report'),
src: vrtReportSrc,
dest: path.join(outDir, 'vrt-report'),
});

const a11yReportSrc = '.buildkite/artifacts/merged_a11y_html_report.gz';
await downloadArtifacts(a11yReportSrc, 'playwright_a11y_merge_and_status');
await decompress({
src: a11yReportSrc,
dest: path.join(outDir, 'a11y-report'),
});

startGroup('Check deployment files');

const hasDocsIndex = fs.existsSync(path.join(outDir, 'index.html'));
const hasStorybookIndex = fs.existsSync(path.join(outDir, 'storybook/index.html'));
const hasE2EIndex = fs.existsSync(path.join(outDir, 'e2e/index.html'));
const hasE2EReportIndex = fs.existsSync(path.join(outDir, 'e2e-report/index.html'));
const hasVrtReportIndex = fs.existsSync(path.join(outDir, 'vrt-report/index.html'));
const hasA11yReportIndex = fs.existsSync(path.join(outDir, 'a11y-report/index.html'));
const missingFiles = [
['docs', hasDocsIndex],
['storybook', hasStorybookIndex],
['e2e server', hasE2EIndex],
['e2e report', hasE2EReportIndex],
['vrt report', hasVrtReportIndex],
['a11y report', hasA11yReportIndex],
]
.filter(([, exists]) => !exists)
.map<string>(([f]) => f as string);
Expand Down
79 changes: 79 additions & 0 deletions .buildkite/scripts/steps/playwright_a11y.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import path from 'path';

import { getMetadata, setMetadata } from 'buildkite-agent-node';

import { updateCheckStatus } from './../../utils/github';
import { exec, downloadArtifacts, startGroup, yarnInstall, getNumber, decompress, compress, bkEnv } from '../../utils';
import { ENV_URL } from '../../utils/constants';

const jobIndex = getNumber(process.env.BUILDKITE_PARALLEL_JOB);
const shardIndex = jobIndex ? jobIndex + 1 : 1;
const jobTotal = getNumber(process.env.BUILDKITE_PARALLEL_JOB_COUNT);

const pwFlags = ['--project=Chrome', '--config=playwright.a11y.config.ts'];

if (jobIndex !== null && jobTotal !== null) {
pwFlags.push(`--shard=${shardIndex}/${jobTotal}`);
}

void (async () => {
await yarnInstall('e2e');

const key = `${bkEnv.checkId}--activeJobs`;
const value = shardIndex === jobTotal ? jobTotal - 1 : Number(await getMetadata(key));
// TODO improve this status logic, not easy to communicate state of parallel steps
const activeJobs = Math.min((Number.isNaN(value) ? 0 : value) + 1, jobTotal ?? 1);
await setMetadata(key, String(activeJobs));

await updateCheckStatus(
{
status: 'in_progress',
},
'playwright_a11y',
`${activeJobs} of ${jobTotal ?? 1} a11y jobs started`,
);

const src = '.buildkite/artifacts/e2e_server.gz';
await downloadArtifacts(src, 'build_e2e');
await decompress({
src,
dest: 'e2e/server',
});

startGroup('Check Architecture');
await exec('arch');

startGroup('Running e2e a11y playwright job');
const reportDir = `reports/a11y_report_${shardIndex}`;
async function postCommandTasks() {
await compress({
src: path.join('e2e', reportDir),
dest: `.buildkite/artifacts/a11y_reports/report_${shardIndex}.gz`,
});
}

const command = `yarn playwright test ${pwFlags.join(' ')}`;

try {
await exec(command, {
cwd: 'e2e',
env: {
[ENV_URL]: 'http://127.0.0.1:9002',
PLAYWRIGHT_HTML_REPORT: reportDir,
PLAYWRIGHT_JSON_OUTPUT_NAME: `reports/a11y-json/report_${shardIndex}.json`,
},
});
await postCommandTasks();
} catch (error) {
await postCommandTasks();
throw error;
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void (async () => {
{
status: 'in_progress',
},
'playwright',
'playwright_vrt',
`${activeJobs} of ${jobTotal ?? 1} jobs started`,
);

Expand All @@ -98,12 +98,12 @@ void (async () => {
// TODO Fix this duplicate script that allows us to skip root node install on all e2e test runners
await exec('node ./e2e/scripts/extract_examples.js');

startGroup('Running e2e playwright job');
const reportDir = `reports/report_${shardIndex}`;
startGroup('Running e2e vrt playwright job');
const reportDir = `reports/vrt_report_${shardIndex}`;
async function postCommandTasks() {
await compress({
src: path.join('e2e', reportDir),
dest: `.buildkite/artifacts/e2e_reports/report_${shardIndex}.gz`,
dest: `.buildkite/artifacts/vrt_reports/report_${shardIndex}.gz`,
});

if (bkEnv.steps.playwright.updateScreenshots) {
Expand All @@ -119,7 +119,7 @@ void (async () => {
env: {
[ENV_URL]: 'http://127.0.0.1:9002',
PLAYWRIGHT_HTML_REPORT: reportDir,
PLAYWRIGHT_JSON_OUTPUT_NAME: `reports/json/report_${shardIndex}.json`,
PLAYWRIGHT_JSON_OUTPUT_NAME: `reports/vrt-json/report_${shardIndex}.json`,
},
});
await postCommandTasks();
Expand Down
8 changes: 7 additions & 1 deletion .buildkite/steps/firebase_deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ export const firebaseDeployStep = createStep<CustomCommandStep>(() => {
label: ':firebase: Deploy - firebase',
key: 'deploy_fb',
allow_dependency_failure: true,
depends_on: ['build_docs', 'build_storybook', 'build_e2e', 'playwright_merge_and_status'],
depends_on: [
'build_docs',
'build_storybook',
'build_e2e',
'playwright_vrt_merge_and_status',
'playwright_a11y_merge_and_status',
],
commands: ['npx ts-node .buildkite/scripts/steps/firebase_deploy.ts'],
env: {
ECH_CHECK_ID: 'deploy_fb',
Expand Down
3 changes: 2 additions & 1 deletion .buildkite/steps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export * from './eslint';
export * from './api_check';
export * from './type_check';
export * from './prettier';
export * from './playwright';
export * from './playwright_vrt';
export * from './playwright_a11y';
export * from './docs';
export * from './storybook';
export * from './e2e_server';
Expand Down
60 changes: 60 additions & 0 deletions .buildkite/steps/playwright_a11y.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { CustomGroupStep } from '../utils';
import { createStep, commandStepDefaults, Plugins } from '../utils';

export const playwrightA11yStep = createStep<CustomGroupStep>(() => {
const skip = false;
const parallelKey = 'playwright_a11y__parallel-step';
return {
group: ':playwright: Playwright e2e A11Y',
key: 'playwright_a11y',
skip,
steps: [
{
...commandStepDefaults,
label: ':playwright: Playwright e2e A11Y',
skip,
parallelism: 1,
retry: {
automatic: [
{
// Playwright tests likely failed correctly
exit_status: 1,
limit: 0,
},
{
// Something went wrong with step command setup, retry once
exit_status: '*',
limit: 1,
},
],
},
timeout_in_minutes: 10, // Shorter timeout for a11y tests
key: parallelKey,
depends_on: ['build_e2e'],
plugins: [Plugins.docker.playwright()],
artifact_paths: ['.buildkite/artifacts/a11y_reports/*', 'e2e/reports/a11y-json/*'],
commands: ['npx ts-node .buildkite/scripts/steps/playwright_a11y.ts'],
},
{
...commandStepDefaults,
key: 'playwright_a11y_merge_and_status',
label: ':playwright: Set a11y group status and merge reports',
skip,
allow_dependency_failure: true,
depends_on: [{ step: parallelKey, allow_failure: true }],
commands: ['npx ts-node .buildkite/scripts/steps/e2e_reports.ts'],
env: {
ECH_CHECK_ID: 'playwright_a11y',
},
},
],
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
import type { CustomGroupStep } from '../utils';
import { createStep, commandStepDefaults, Plugins } from '../utils';

export const playwrightStep = createStep<CustomGroupStep>(() => {
export const playwrightVrtStep = createStep<CustomGroupStep>(() => {
const skip = false;
const parallelKey = 'playwright__parallel-step';
const parallelKey = 'playwright_vrt__parallel-step';
return {
group: ':playwright: Playwright e2e',
key: 'playwright',
group: ':playwright: Playwright e2e VRT',
key: 'playwright_vrt',
skip,
steps: [
{
...commandStepDefaults,
label: ':playwright: Playwright e2e',
label: ':playwright: Playwright e2e VRT',
skip,
parallelism: 10,
retry: {
Expand All @@ -41,23 +41,23 @@ export const playwrightStep = createStep<CustomGroupStep>(() => {
depends_on: ['build_e2e'],
plugins: [Plugins.docker.playwright()],
artifact_paths: [
'.buildkite/artifacts/e2e_reports/*',
'.buildkite/artifacts/vrt_reports/*',
'.buildkite/artifacts/screenshots/*',
'.buildkite/artifacts/screenshot_meta/*',
'e2e/reports/json/*',
],
commands: ['npx ts-node .buildkite/scripts/steps/playwright.ts'],
commands: ['npx ts-node .buildkite/scripts/steps/playwright_vrt.ts'],
},
{
...commandStepDefaults,
key: 'playwright_merge_and_status',
label: ':playwright: Set group status and merge reports',
key: 'playwright_vrt_merge_and_status',
label: ':playwright: Set vrt group status and merge reports',
skip,
allow_dependency_failure: true,
depends_on: [{ step: parallelKey, allow_failure: true }],
commands: ['npx ts-node .buildkite/scripts/steps/e2e_reports.ts'],
env: {
ECH_CHECK_ID: 'playwright',
ECH_CHECK_ID: 'playwright_vrt',
},
},
],
Expand Down
3 changes: 2 additions & 1 deletion .buildkite/utils/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export const getBuildConfig = (): BuildConfig => {
{ name: 'Deploy - firebase', id: 'deploy_fb' },
...(bkEnv.isMainBranch ? [{ name: 'Deploy - GitHub Pages', id: 'deploy_ghp' }] : []),
{ name: 'Jest', id: 'jest' },
{ name: 'Playwright e2e', id: 'playwright' },
{ name: 'Playwright e2e VRT', id: 'playwright_vrt' },
{ name: 'Playwright e2e A11Y', id: 'playwright_a11y' },
],
};
};
Expand Down
Loading