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

[ts] migrate root test dir to project refs #99148

Merged
merged 8 commits into from
Jun 4, 2021
6 changes: 6 additions & 0 deletions packages/kbn-test/src/functional_test_runner/public_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ export interface GenericFtrProviderContext<
getService(serviceName: 'failureMetadata'): FailureMetadata;
getService<T extends keyof ServiceMap>(serviceName: T): ServiceMap[T];

/**
* Get the instance of a page object
* @param pageObjectName
*/
getPageObject<K extends keyof PageObjectMap>(pageObjectName: K): PageObjectMap[K];

/**
* Get a map of PageObjects
* @param pageObjects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
* Side Public License, v 1.
*/

import { GenericFtrProviderContext } from '@kbn/test';
import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test';

import { pageObjects } from './page_objects';
import { services } from './services';

export type FtrProviderContext = GenericFtrProviderContext<typeof services, typeof pageObjects>;
export class FtrService extends GenericFtrService<FtrProviderContext> {}
136 changes: 67 additions & 69 deletions test/accessibility/services/a11y/a11y.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import chalk from 'chalk';
import testSubjectToCss from '@kbn/test-subj-selector';

import { FtrProviderContext } from '../../ftr_provider_context';
import { FtrService } from '../../ftr_provider_context';
import { AxeReport, printResult } from './axe_report';
// @ts-ignore JS that is run in browser as is
import { analyzeWithAxe, analyzeWithAxeWithClient } from './analyze_with_axe';
Expand All @@ -33,86 +33,84 @@ export const normalizeResult = (report: any) => {
return report.result as false | AxeReport;
};

export function A11yProvider({ getService }: FtrProviderContext) {
const browser = getService('browser');
const Wd = getService('__webdriver__');

/**
* Accessibility testing service using the Axe (https://www.deque.com/axe/)
* toolset to validate a11y rules similar to ESLint. In order to test against
* the rules we must load up the UI and feed a full HTML snapshot into Axe.
*/
return new (class Accessibility {
public async testAppSnapshot(options: TestOptions = {}) {
const context = this.getAxeContext(true, options.excludeTestSubj);
const report = await this.captureAxeReport(context);
await this.testAxeReport(report);
}
/**
* Accessibility testing service using the Axe (https://www.deque.com/axe/)
* toolset to validate a11y rules similar to ESLint. In order to test against
* the rules we must load up the UI and feed a full HTML snapshot into Axe.
*/
export class AccessibilityService extends FtrService {
private readonly browser = this.ctx.getService('browser');
private readonly Wd = this.ctx.getService('__webdriver__');
spalger marked this conversation as resolved.
Show resolved Hide resolved

public async testAppSnapshot(options: TestOptions = {}) {
const context = this.getAxeContext(true, options.excludeTestSubj);
const report = await this.captureAxeReport(context);
this.assertValidAxeReport(report);
}

public async testGlobalSnapshot(options: TestOptions = {}) {
const context = this.getAxeContext(false, options.excludeTestSubj);
const report = await this.captureAxeReport(context);
await this.testAxeReport(report);
}
public async testGlobalSnapshot(options: TestOptions = {}) {
const context = this.getAxeContext(false, options.excludeTestSubj);
const report = await this.captureAxeReport(context);
this.assertValidAxeReport(report);
}

private getAxeContext(global: boolean, excludeTestSubj?: string | string[]): AxeContext {
return {
include: global ? undefined : [testSubjectToCss('appA11yRoot')],
exclude: ([] as string[])
.concat(excludeTestSubj || [])
.map((ts) => [testSubjectToCss(ts)])
.concat([['[role="graphics-document"][aria-roledescription="visualization"]']]),
};
}
private getAxeContext(global: boolean, excludeTestSubj?: string | string[]): AxeContext {
return {
include: global ? undefined : [testSubjectToCss('appA11yRoot')],
exclude: ([] as string[])
.concat(excludeTestSubj || [])
.map((ts) => [testSubjectToCss(ts)])
.concat([['[role="graphics-document"][aria-roledescription="visualization"]']]),
};
}

private testAxeReport(report: AxeReport) {
const errorMsgs = [];
private assertValidAxeReport(report: AxeReport) {
const errorMsgs = [];

for (const result of report.violations) {
errorMsgs.push(printResult(chalk.red('VIOLATION'), result));
}
for (const result of report.violations) {
errorMsgs.push(printResult(chalk.red('VIOLATION'), result));
}

if (errorMsgs.length) {
throw new Error(`a11y report:\n${errorMsgs.join('\n')}`);
}
if (errorMsgs.length) {
throw new Error(`a11y report:\n${errorMsgs.join('\n')}`);
}
}

private async captureAxeReport(context: AxeContext): Promise<AxeReport> {
const axeOptions = {
reporter: 'v2',
runOnly: ['wcag2a', 'wcag2aa'],
rules: {
'color-contrast': {
enabled: false, // disabled because we have too many failures
},
bypass: {
enabled: false, // disabled because it's too flaky
},
private async captureAxeReport(context: AxeContext): Promise<AxeReport> {
const axeOptions = {
reporter: 'v2',
runOnly: ['wcag2a', 'wcag2aa'],
rules: {
'color-contrast': {
enabled: false, // disabled because we have too many failures
},
};

await (Wd.driver.manage() as any).setTimeouts({
...(await (Wd.driver.manage() as any).getTimeouts()),
script: 600000,
});
bypass: {
enabled: false, // disabled because it's too flaky
},
},
};

const report = normalizeResult(
await browser.executeAsync(analyzeWithAxe, context, axeOptions)
);
await this.Wd.driver.manage().setTimeouts({
...(await this.Wd.driver.manage().getTimeouts()),
script: 600000,
});

if (report !== false) {
return report;
}
const report = normalizeResult(
await this.browser.executeAsync(analyzeWithAxe, context, axeOptions)
);

const withClientReport = normalizeResult(
await browser.executeAsync(analyzeWithAxeWithClient, context, axeOptions)
);
if (report !== false) {
return report;
}

if (withClientReport === false) {
throw new Error('Attempted to analyze with axe but failed to load axe client');
}
const withClientReport = normalizeResult(
await this.browser.executeAsync(analyzeWithAxeWithClient, context, axeOptions)
);

return withClientReport;
if (withClientReport === false) {
throw new Error('Attempted to analyze with axe but failed to load axe client');
}
})();

return withClientReport;
}
}
2 changes: 1 addition & 1 deletion test/accessibility/services/a11y/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
* Side Public License, v 1.
*/

export { A11yProvider } from './a11y';
export * from './a11y';
4 changes: 2 additions & 2 deletions test/accessibility/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
*/

import { services as kibanaFunctionalServices } from '../../functional/services';
import { A11yProvider } from './a11y';
import { AccessibilityService } from './a11y';

export const services = {
...kibanaFunctionalServices,
a11y: A11yProvider,
a11y: AccessibilityService,
};
Loading