diff --git a/src/DetailsView/components/assessment-visualization-enabled-toggle.tsx b/src/DetailsView/components/assessment-visualization-enabled-toggle.tsx
index d3ef06bcf53..461e78ad1c3 100644
--- a/src/DetailsView/components/assessment-visualization-enabled-toggle.tsx
+++ b/src/DetailsView/components/assessment-visualization-enabled-toggle.tsx
@@ -1,13 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { GeneratedAssessmentInstance } from 'common/types/store-data/assessment-result-data';
-import { isEmpty } from 'lodash';
import { BaseVisualHelperToggle } from './base-visual-helper-toggle';
export class AssessmentVisualizationEnabledToggle extends BaseVisualHelperToggle {
- protected isDisabled(filteredInstances: GeneratedAssessmentInstance<{}, {}>[]): boolean {
- return isEmpty(filteredInstances);
+ protected isDisabled(instances: GeneratedAssessmentInstance<{}, {}>[]): boolean {
+ return !this.isAnyInstanceVisualizable(instances);
}
protected isChecked(instances: GeneratedAssessmentInstance<{}, {}>[]): boolean {
@@ -28,10 +27,16 @@ export class AssessmentVisualizationEnabledToggle extends BaseVisualHelperToggle
};
private isAnyInstanceVisible(instances: GeneratedAssessmentInstance<{}, {}>[]): boolean {
+ const testStep = this.props.assessmentNavState.selectedTestSubview;
return instances.some(
- instance =>
- instance.testStepResults[this.props.assessmentNavState.selectedTestSubview]
- .isVisualizationEnabled,
+ instance => instance.testStepResults[testStep].isVisualizationEnabled,
+ );
+ }
+
+ private isAnyInstanceVisualizable(instances: GeneratedAssessmentInstance<{}, {}>[]): boolean {
+ const testStep = this.props.assessmentNavState.selectedTestSubview;
+ return instances.some(
+ instance => instance.testStepResults[testStep].isVisualizationSupported,
);
}
}
diff --git a/src/assessments/assessment-builder.tsx b/src/assessments/assessment-builder.tsx
index b150d41e3b5..a01c3f3bed5 100644
--- a/src/assessments/assessment-builder.tsx
+++ b/src/assessments/assessment-builder.tsx
@@ -10,6 +10,7 @@ import { RequirementComparer } from 'common/assessment/requirement-comparer';
import { AssessmentVisualizationConfiguration } from 'common/configs/assessment-visualization-configuration';
import { Messages } from 'common/messages';
import { ManualTestStatus } from 'common/types/manual-test-status';
+import { InstanceIdToInstanceDataMap } from 'common/types/store-data/assessment-result-data';
import { FeatureFlagStoreData } from 'common/types/store-data/feature-flag-store-data';
import { AssessmentScanData, ScanData } from 'common/types/store-data/visualization-store-data';
import {
@@ -52,6 +53,15 @@ export class AssessmentBuilder {
requirement.getInstanceStatus = AssessmentBuilder.getInstanceStatus;
}
+ if (!requirement.getInitialManualTestStatus) {
+ requirement.getInitialManualTestStatus = AssessmentBuilder.getInitialManualTestStatus;
+ }
+
+ if (!requirement.isVisualizationSupportedForResult) {
+ requirement.isVisualizationSupportedForResult =
+ AssessmentBuilder.isVisualizationSupportedForResult;
+ }
+
if (!requirement.getInstanceStatusColumns) {
requirement.getInstanceStatusColumns = AssessmentBuilder.getInstanceStatusColumns;
}
@@ -75,6 +85,16 @@ export class AssessmentBuilder {
return ManualTestStatus.UNKNOWN;
}
+ private static getInitialManualTestStatus(
+ instances: InstanceIdToInstanceDataMap,
+ ): ManualTestStatus {
+ return ManualTestStatus.UNKNOWN;
+ }
+
+ private static isVisualizationSupportedForResult(result: DecoratedAxeNodeResult): boolean {
+ return true;
+ }
+
private static getInstanceStatusColumns(): Readonly[] {
return [
{
diff --git a/src/assessments/landmarks/auto-pass-if-no-landmarks.ts b/src/assessments/landmarks/auto-pass-if-no-landmarks.ts
new file mode 100644
index 00000000000..4a2d28673a8
--- /dev/null
+++ b/src/assessments/landmarks/auto-pass-if-no-landmarks.ts
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import { ManualTestStatus } from 'common/types/manual-test-status';
+import { InstanceIdToInstanceDataMap } from 'common/types/store-data/assessment-result-data';
+import { some } from 'lodash';
+
+export function autoPassIfNoLandmarks(instanceData: InstanceIdToInstanceDataMap): ManualTestStatus {
+ const someInstanceHasLandmarkRole = some(
+ Object.values(instanceData),
+ instance => instance.propertyBag != null && instance.propertyBag['role'] != null,
+ );
+
+ return someInstanceHasLandmarkRole ? ManualTestStatus.UNKNOWN : ManualTestStatus.PASS;
+}
diff --git a/src/assessments/landmarks/does-result-have-main-role.ts b/src/assessments/landmarks/does-result-have-main-role.ts
new file mode 100644
index 00000000000..5a99b888217
--- /dev/null
+++ b/src/assessments/landmarks/does-result-have-main-role.ts
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import { DecoratedAxeNodeResult } from 'injected/scanner-utils';
+import { some } from 'lodash';
+
+export function doesResultHaveMainRole(result: DecoratedAxeNodeResult): boolean {
+ // This 'role' data is populated by the unique-landmark rule, which considers
+ // both explicit role attributes and implicit roles based on tag name
+ return (
+ some(result.any, checkResult => checkResult.data['role'] === 'main') ||
+ some(result.all, checkResult => checkResult.data['role'] === 'main')
+ );
+}
diff --git a/src/assessments/landmarks/test-steps/no-repeating-content.tsx b/src/assessments/landmarks/test-steps/no-repeating-content.tsx
index 9a0a84860b5..f10f2c03485 100644
--- a/src/assessments/landmarks/test-steps/no-repeating-content.tsx
+++ b/src/assessments/landmarks/test-steps/no-repeating-content.tsx
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
import * as React from 'react';
+import { doesResultHaveMainRole } from 'assessments/landmarks/does-result-have-main-role';
import { VisualizationType } from 'common/types/visualization-type';
import { link } from 'content/link';
import * as content from 'content/test/landmarks/no-repeating-content';
@@ -10,10 +11,14 @@ import { AnalyzerConfigurationFactory } from '../../common/analyzer-configuratio
import { ManualTestRecordYourResults } from '../../common/manual-test-record-your-results';
import * as Markup from '../../markup';
import { Requirement } from '../../types/requirement';
+import { autoPassIfNoLandmarks } from '../auto-pass-if-no-landmarks';
import { LandmarkTestStep } from './test-steps';
const description: JSX.Element = (
- The main landmark must not contain any blocks of content that repeat across pages.
+
+ The main landmark must not contain any blocks of content
+ that repeat across pages.
+
);
const howToTest: JSX.Element = (
@@ -22,10 +27,33 @@ const howToTest: JSX.Element = (
The visual helper for this requirement highlights the page's{' '}
main landmark.
+
-
The visual helper for this requirement highlights the page's main landmark.
+
+ The visual helper for this requirement highlights the page's{' '}
+ main landmark.
+
+
+
+ Note: If no landmarks are found, this requirement will automatically be marked as
+ pass.
+
+
-
- In the target page, examine the main landmark to
- verify that it contains all of the page's primary content.
+
Examine the target page to verify that all of the following are true:
+
+ -
+ The page has exactly one main landmark,
+ and
+
+ -
+ The main landmark contains all of the
+ page's primary content.
+
+
+
+ Exception: If a page has nested document or{' '}
+ application roles (typically applied to{' '}
+ or elements),
+ each nested document or application may also{' '}
+ have one main landmark.
+
@@ -35,11 +65,13 @@ export const PrimaryContent: Requirement = {
description,
howToTest,
isManual: true,
+ getInitialManualTestStatus: autoPassIfNoLandmarks,
+ isVisualizationSupportedForResult: doesResultHaveMainRole,
guidanceLinks: [link.WCAG_1_3_1, link.WCAG_2_4_1],
getAnalyzer: provider =>
provider.createRuleAnalyzer(
AnalyzerConfigurationFactory.forScanner({
- rules: ['main-landmark'],
+ rules: ['unique-landmark'],
key: LandmarkTestStep.primaryContent,
testType: VisualizationType.LandmarksAssessment,
}),
diff --git a/src/assessments/types/requirement.ts b/src/assessments/types/requirement.ts
index 2656094ff08..8ccb7fc4560 100644
--- a/src/assessments/types/requirement.ts
+++ b/src/assessments/types/requirement.ts
@@ -5,6 +5,7 @@ import { ManualTestStatus } from 'common/types/manual-test-status';
import {
AssessmentNavState,
GeneratedAssessmentInstance,
+ InstanceIdToInstanceDataMap,
} from 'common/types/store-data/assessment-result-data';
import { FeatureFlagStoreData } from 'common/types/store-data/feature-flag-store-data';
import { DetailsViewActionMessageCreator } from 'DetailsView/actions/details-view-action-message-creator';
@@ -39,10 +40,17 @@ export interface Requirement {
addFailureInstruction?: string;
infoAndExamples?: ContentPageComponent;
isManual: boolean;
+ // This is for semi-manual cases where we can't present a list of instances like an assisted
+ // test would, but can infer a PASS or FAIL state. If not specified, acts like () => UNKNOWN.
+ getInitialManualTestStatus?: (instances: InstanceIdToInstanceDataMap) => ManualTestStatus;
guidanceLinks: HyperlinkDefinition[];
columnsConfig?: InstanceTableColumn[];
getAnalyzer?: (provider: AnalyzerProvider) => Analyzer;
getVisualHelperToggle?: (props: VisualHelperToggleConfig) => JSX.Element;
+ // Any results this returns false for will be omitted from visual helper displays, but still
+ // present for the purposes of instance lists or getInitialManualTestStatus. By default, all
+ // results support visualization.
+ isVisualizationSupportedForResult?: (result: DecoratedAxeNodeResult) => boolean;
visualizationInstanceProcessor?: VisualizationInstanceProcessorCallback<
PropertyBags,
PropertyBags
diff --git a/src/background/assessment-data-converter.ts b/src/background/assessment-data-converter.ts
index 0c5c7d24522..edc68817be1 100644
--- a/src/background/assessment-data-converter.ts
+++ b/src/background/assessment-data-converter.ts
@@ -29,6 +29,7 @@ export class AssessmentDataConverter {
stepName: string,
generateInstanceIdentifier: (instance: UniquelyIdentifiableInstances) => string,
getInstanceStatus: (result: DecoratedAxeNodeResult) => ManualTestStatus,
+ isVisualizationSupported: (result: DecoratedAxeNodeResult) => boolean,
): AssessmentInstancesMap {
let instancesMap: AssessmentInstancesMap = {};
@@ -51,6 +52,7 @@ export class AssessmentDataConverter {
stepName,
ruleResult,
getInstanceStatus,
+ isVisualizationSupported,
);
}
});
@@ -98,6 +100,7 @@ export class AssessmentDataConverter {
testStep: string,
ruleResult: DecoratedAxeNodeResult,
getInstanceStatus: (result: DecoratedAxeNodeResult) => ManualTestStatus,
+ isVisualizationSupported: (result: DecoratedAxeNodeResult) => boolean,
): GeneratedAssessmentInstance {
const target: string[] = elementAxeResult.target;
let testStepResults = {};
@@ -114,6 +117,7 @@ export class AssessmentDataConverter {
ruleResult,
elementAxeResult,
getInstanceStatus,
+ isVisualizationSupported,
);
let actualPropertyBag = {
@@ -163,6 +167,7 @@ export class AssessmentDataConverter {
status: ManualTestStatus.UNKNOWN,
isCapturedByUser: false,
failureSummary: null,
+ isVisualizationSupported: true,
isVisualizationEnabled: true,
isVisible: true,
};
@@ -172,12 +177,14 @@ export class AssessmentDataConverter {
ruleResult: DecoratedAxeNodeResult,
elementAxeResult: HtmlElementAxeResults,
getInstanceStatus: (result: DecoratedAxeNodeResult) => ManualTestStatus,
+ isVisualizationSupported: (result: DecoratedAxeNodeResult) => boolean,
): TestStepResult {
return {
id: ruleResult.id,
status: getInstanceStatus(ruleResult),
isCapturedByUser: false,
failureSummary: ruleResult.failureSummary,
+ isVisualizationSupported: isVisualizationSupported(ruleResult),
isVisualizationEnabled: false,
isVisible: true,
};
diff --git a/src/background/stores/assessment-store.ts b/src/background/stores/assessment-store.ts
index e8f9e7d7ce9..a2a5e4108d8 100644
--- a/src/background/stores/assessment-store.ts
+++ b/src/background/stores/assessment-store.ts
@@ -11,6 +11,7 @@ import {
AssessmentData,
AssessmentStoreData,
GeneratedAssessmentInstance,
+ InstanceIdToInstanceDataMap,
TestStepResult,
UserCapturedInstance,
} from 'common/types/store-data/assessment-result-data';
@@ -272,16 +273,17 @@ export class AssessmentStore extends BaseStoreImpl
{
private onChangeAssessmentVisualizationStateForAll = (
payload: ChangeInstanceSelectionPayload,
): void => {
- const config = this.assessmentsProvider
- .forType(payload.test)
- .getVisualizationConfiguration();
+ const { test, requirement } = payload;
+ const config = this.assessmentsProvider.forType(test).getVisualizationConfiguration();
const assessmentDataMap = config.getAssessmentData(this.state)
.generatedAssessmentInstancesMap;
+
forEach(assessmentDataMap, val => {
- const stepResult = val.testStepResults[payload.requirement];
+ const stepResult = val.testStepResults[requirement];
if (stepResult != null) {
- stepResult.isVisualizationEnabled = payload.isVisualizationEnabled;
+ stepResult.isVisualizationEnabled =
+ stepResult.isVisualizationSupported && payload.isVisualizationEnabled;
}
});
@@ -318,15 +320,14 @@ export class AssessmentStore extends BaseStoreImpl {
private onChangeAssessmentVisualizationState = (
payload: ChangeInstanceSelectionPayload,
): void => {
- const config = this.assessmentsProvider
- .forType(payload.test)
- .getVisualizationConfiguration();
+ const { test, requirement } = payload;
+ const config = this.assessmentsProvider.forType(test).getVisualizationConfiguration();
const assessmentData = config.getAssessmentData(this.state);
- const stepResult: TestStepResult =
- assessmentData.generatedAssessmentInstancesMap[payload.selector].testStepResults[
- payload.requirement
- ];
- stepResult.isVisualizationEnabled = payload.isVisualizationEnabled;
+ const instance = assessmentData.generatedAssessmentInstancesMap[payload.selector];
+ const stepResult: TestStepResult = instance.testStepResults[requirement];
+
+ stepResult.isVisualizationEnabled =
+ stepResult.isVisualizationSupported && payload.isVisualizationEnabled;
this.emitChanged();
};
@@ -382,6 +383,7 @@ export class AssessmentStore extends BaseStoreImpl {
step,
config.getInstanceIdentiferGenerator(step),
stepConfig.getInstanceStatus,
+ stepConfig.isVisualizationSupportedForResult,
);
assessmentData.generatedAssessmentInstancesMap = generatedAssessmentInstancesMap;
assessmentData.testStepStatus[step].isStepScanned = true;
@@ -432,12 +434,38 @@ export class AssessmentStore extends BaseStoreImpl {
testStepName: string,
testType: VisualizationType,
): void {
- const isManual = this.assessmentsProvider.getStep(testType, testStepName).isManual;
- if (isManual !== true) {
+ const step = this.assessmentsProvider.getStep(testType, testStepName);
+ const { isManual, getInitialManualTestStatus } = step;
+
+ if (isManual) {
+ this.applyInitialManualTestStatus(
+ assessmentData,
+ testStepName,
+ testType,
+ getInitialManualTestStatus,
+ );
+ } else {
this.updateTestStepStatusForGeneratedInstances(assessmentData, testStepName);
}
}
+ private applyInitialManualTestStatus(
+ assessmentData: AssessmentData,
+ testStepName: string,
+ testType: VisualizationType,
+ getInitialManualTestStatus: (InstanceIdToInstanceDataMap) => ManualTestStatus,
+ ): void {
+ const originalStatus = assessmentData.manualTestStepResultMap[testStepName].status;
+ if (originalStatus !== ManualTestStatus.UNKNOWN) {
+ return; // Never override an explicitly set status
+ }
+
+ const instanceMap = assessmentData.generatedAssessmentInstancesMap;
+ const status = getInitialManualTestStatus(instanceMap);
+ assessmentData.manualTestStepResultMap[testStepName].status = status;
+ this.updateManualTestStepStatus(assessmentData, testStepName, testType);
+ }
+
private getGroupResult(
instanceMap: DictionaryStringTo,
testStepName: string,
diff --git a/src/common/types/store-data/assessment-result-data.ts b/src/common/types/store-data/assessment-result-data.ts
index a44c441affa..f90213f4da2 100644
--- a/src/common/types/store-data/assessment-result-data.ts
+++ b/src/common/types/store-data/assessment-result-data.ts
@@ -61,6 +61,7 @@ export interface TestStepResult {
status: ManualTestStatus;
isCapturedByUser: boolean;
failureSummary: string;
+ isVisualizationSupported: boolean;
isVisualizationEnabled: boolean;
isVisible: boolean;
originalStatus?: ManualTestStatus;
diff --git a/src/scanner/custom-rule-configurations.ts b/src/scanner/custom-rule-configurations.ts
index 4791b40d7c2..481f380563f 100644
--- a/src/scanner/custom-rule-configurations.ts
+++ b/src/scanner/custom-rule-configurations.ts
@@ -10,7 +10,6 @@ import { frameTitleConfiguration } from './custom-rules/frame-title';
import { headerRuleConfiguration } from './custom-rules/header-rule';
import { headingConfiguration } from './custom-rules/heading-rule';
import { imageConfiguration } from './custom-rules/image-rule';
-import { landmarkConfiguration } from './custom-rules/landmark-rule';
import { linkFunctionConfiguration } from './custom-rules/link-function';
import { linkPurposeConfiguration } from './custom-rules/link-purpose';
import { nativeWidgetsDefaultConfiguration } from './custom-rules/native-widgets-default';
@@ -24,7 +23,6 @@ import { RuleConfiguration } from './iruleresults';
export const configuration: RuleConfiguration[] = [
headingConfiguration,
colorConfiguration,
- landmarkConfiguration,
uniqueLandmarkConfiguration,
imageConfiguration,
textAlternativeConfiguration,
diff --git a/src/scanner/custom-rules/landmark-rule.ts b/src/scanner/custom-rules/landmark-rule.ts
deleted file mode 100644
index 778f201e4a1..00000000000
--- a/src/scanner/custom-rules/landmark-rule.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { RuleConfiguration } from '../iruleresults';
-
-const landmarkCheckId: string = 'unique-landmark';
-
-export const landmarkConfiguration: RuleConfiguration = {
- checks: [],
- rule: {
- id: 'main-landmark',
- selector: '[role=main], main',
- any: [landmarkCheckId],
- enabled: false,
- },
-};
diff --git a/src/tests/unit/common/visual-helper-toggle-config-builder.ts b/src/tests/unit/common/visual-helper-toggle-config-builder.ts
index 23a86eb2aec..065653bf9b5 100644
--- a/src/tests/unit/common/visual-helper-toggle-config-builder.ts
+++ b/src/tests/unit/common/visual-helper-toggle-config-builder.ts
@@ -52,6 +52,7 @@ export class VisualHelperToggleConfigBuilder extends BaseDataBuilder,
} as GeneratedAssessmentInstance,
@@ -68,7 +70,8 @@ export class VisualHelperToggleConfigBuilder extends BaseDataBuilder,
} as GeneratedAssessmentInstance,
@@ -102,4 +105,29 @@ export class VisualHelperToggleConfigBuilder extends BaseDataBuilder,
+ } as GeneratedAssessmentInstance,
+ 'selector-2': {
+ testStepResults: {
+ [this.stepKey]: {
+ id: 'id1',
+ status: ManualTestStatus.PASS,
+ isVisualizationEnabled: false,
+ isVisualizationSupported: false,
+ } as TestStepResult,
+ } as AssessmentResultType,
+ } as GeneratedAssessmentInstance,
+ };
+ return this;
+ }
}
diff --git a/src/tests/unit/tests/DetailsView/components/assessment-visualization-enabled-toggle.test.tsx b/src/tests/unit/tests/DetailsView/components/assessment-visualization-enabled-toggle.test.tsx
index e9b8e86d8a1..99a457b0984 100644
--- a/src/tests/unit/tests/DetailsView/components/assessment-visualization-enabled-toggle.test.tsx
+++ b/src/tests/unit/tests/DetailsView/components/assessment-visualization-enabled-toggle.test.tsx
@@ -1,200 +1,234 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import * as Enzyme from 'enzyme';
-import * as React from 'react';
-import { IMock, Mock, Times } from 'typemoq';
import {
VisualizationToggle,
VisualizationToggleProps,
-} from '../../../../../common/components/visualization-toggle';
-import { DetailsViewActionMessageCreator } from '../../../../../DetailsView/actions/details-view-action-message-creator';
-import { AssessmentVisualizationEnabledToggle } from '../../../../../DetailsView/components/assessment-visualization-enabled-toggle';
-import { visualHelperText } from '../../../../../DetailsView/components/base-visual-helper-toggle';
-import { VisualHelperToggleConfigBuilder } from '../../../common/visual-helper-toggle-config-builder';
-import { VisualizationTogglePropsBuilder } from '../../../common/visualization-toggle-props-builder';
+} from 'common/components/visualization-toggle';
+import { DetailsViewActionMessageCreator } from 'DetailsView/actions/details-view-action-message-creator';
+import { AssessmentVisualizationEnabledToggle } from 'DetailsView/components/assessment-visualization-enabled-toggle';
+import { visualHelperText } from 'DetailsView/components/base-visual-helper-toggle';
+import * as Enzyme from 'enzyme';
+import * as React from 'react';
+import { VisualHelperToggleConfigBuilder } from 'tests/unit/common/visual-helper-toggle-config-builder';
+import { VisualizationTogglePropsBuilder } from 'tests/unit/common/visualization-toggle-props-builder';
+import { IMock, Mock, Times } from 'typemoq';
describe('AssessmentVisualizationEnabledToggle', () => {
const actionMessageCreatorMock: IMock = Mock.ofType(
DetailsViewActionMessageCreator,
);
- it('render with disabled message', () => {
- const props = new VisualHelperToggleConfigBuilder()
- .withToggleStepEnabled(true)
- .withToggleStepScanned(false)
- .withActionMessageCreator(actionMessageCreatorMock.object)
- .withEmptyFilteredMap()
- .build();
+ describe('render', () => {
+ it('is disabled when no instances exist', () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(true)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withEmptyFilteredMap()
+ .build();
- const wrapper = Enzyme.shallow();
+ const testSubject = Enzyme.shallow();
- const visualHelperClass = 'visual-helper';
- const toggleDiv = wrapper.find(`.${visualHelperClass}`);
+ expectDisabledTextLayout(testSubject);
- expect(toggleDiv.exists()).toBeTruthy();
+ const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
+ .with('checked', false)
+ .with('disabled', true)
+ .build();
- const textDiv = toggleDiv.find(`.${visualHelperClass}-text`);
+ expectChildVisualizationToggleWith(expectedToggleProps, testSubject);
+ });
- expect(textDiv.exists()).toBeTruthy();
- expect(textDiv.childAt(0).text()).toEqual(visualHelperText);
+ it("is disabled when only instances that don't support visualization exist", () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(true)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withNonEmptyFilteredMap(false, false)
+ .build();
- const noMatchesWarningClass = 'no-matching-elements';
- expect(wrapper.find(`.${noMatchesWarningClass}`).exists()).toBeTruthy();
+ const testSubject = Enzyme.shallow();
- const toggle = wrapper.find(VisualizationToggle);
+ expectDisabledTextLayout(testSubject);
- const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
- .with('checked', false)
- .with('disabled', true)
- .build();
+ const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
+ .with('checked', false)
+ .with('disabled', true)
+ .build();
- assertVisualizationToggle(expectedToggleProps, toggle);
- });
+ expectChildVisualizationToggleWith(expectedToggleProps, testSubject);
+ });
- it('render: toggle not disabled', () => {
- const props = new VisualHelperToggleConfigBuilder()
- .withToggleStepEnabled(true)
- .withToggleStepScanned(false)
- .withActionMessageCreator(actionMessageCreatorMock.object)
- .withNonEmptyFilteredMap()
- .build();
+ it('is enabled but unchecked if step is enabled but all instance visualizations are disabled', () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(true)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withNonEmptyFilteredMap(false)
+ .build();
- const wrapper = Enzyme.shallow();
+ const testSubject = Enzyme.shallow();
- const visualHelperClass = 'visual-helper';
- const toggleDiv = wrapper.find(`.${visualHelperClass}`);
+ expectEnabledTextLayout(testSubject);
- expect(toggleDiv.exists()).toBeTruthy();
+ const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
+ .with('checked', false)
+ .with('disabled', false)
+ .build();
- const textDiv = toggleDiv.find(`.${visualHelperClass}-text`);
+ expectChildVisualizationToggleWith(expectedToggleProps, testSubject);
+ });
- expect(textDiv.exists()).toBeTruthy();
- expect(textDiv.childAt(0).text()).toEqual(visualHelperText);
- expect(wrapper.find('strong').exists()).toBeFalsy();
- const toggle = wrapper.find(VisualizationToggle);
+ it('is enabled and checked if step and instance visualizations are both enabled', () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(false)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withNonEmptyFilteredMap(true)
+ .build();
- const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
- .with('checked', false)
- .with('disabled', false)
- .build();
+ const testSubject = Enzyme.shallow();
- assertVisualizationToggle(expectedToggleProps, toggle);
- });
+ expectEnabledTextLayout(testSubject);
- it('render: have non empty instance map with a visible instance', () => {
- const props = new VisualHelperToggleConfigBuilder()
- .withToggleStepEnabled(false)
- .withToggleStepScanned(false)
- .withActionMessageCreator(actionMessageCreatorMock.object)
- .withNonEmptyFilteredMap(true)
- .build();
+ const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
+ .with('checked', true)
+ .with('disabled', false)
+ .build();
- const wrapper = Enzyme.shallow();
+ expectChildVisualizationToggleWith(expectedToggleProps, testSubject);
+ });
- const visualHelperClass = 'visual-helper';
- const toggleDiv = wrapper.find(`.${visualHelperClass}`);
+ it("is enabled and checked if some instances support visualization and some don't", () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(false)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withMixedVisualizationSupportFilteredMap()
+ .build();
- expect(toggleDiv.exists()).toBeTruthy();
+ const testSubject = Enzyme.shallow();
- const textDiv = toggleDiv.find(`.${visualHelperClass}-text`);
+ expectEnabledTextLayout(testSubject);
- expect(textDiv.exists()).toBeTruthy();
- expect(textDiv.childAt(0).text()).toEqual(visualHelperText);
- expect(wrapper.find('strong').exists()).toBeFalsy();
+ const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
+ .with('checked', true)
+ .with('disabled', false)
+ .build();
- const toggle = wrapper.find(VisualizationToggle);
+ expectChildVisualizationToggleWith(expectedToggleProps, testSubject);
+ });
- const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
- .with('checked', true)
- .with('disabled', false)
- .build();
+ it('is enabled and unchecked if step and instance visualizations are both disabled', () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(false)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withNonEmptyFilteredMap(false)
+ .build();
- assertVisualizationToggle(expectedToggleProps, toggle);
- });
+ const testSubject = Enzyme.shallow();
- it('render: have non empty instance map without a visible instance', () => {
- const props = new VisualHelperToggleConfigBuilder()
- .withToggleStepEnabled(false)
- .withToggleStepScanned(false)
- .withActionMessageCreator(actionMessageCreatorMock.object)
- .withNonEmptyFilteredMap()
- .build();
+ expectEnabledTextLayout(testSubject);
- const wrapper = Enzyme.shallow();
+ const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
+ .with('checked', false)
+ .with('disabled', false)
+ .build();
- const visualHelperClass = 'visual-helper';
- const toggleDiv = wrapper.find(`.${visualHelperClass}`);
+ expectChildVisualizationToggleWith(expectedToggleProps, testSubject);
+ });
- expect(toggleDiv.exists()).toBeTruthy();
+ function expectEnabledTextLayout(
+ testSubject: Enzyme.ShallowWrapper,
+ ): void {
+ const visualHelperClass = 'visual-helper';
+ const toggleDiv = testSubject.find(`.${visualHelperClass}`);
- const textDiv = toggleDiv.find(`.${visualHelperClass}-text`);
+ expect(toggleDiv.exists()).toBeTruthy();
- expect(textDiv.exists()).toBeTruthy();
- expect(textDiv.childAt(0).text()).toEqual(visualHelperText);
- expect(wrapper.find('strong').exists()).toBeFalsy();
- const toggle = wrapper.find(VisualizationToggle);
+ const textDiv = toggleDiv.find(`.${visualHelperClass}-text`);
- const expectedToggleProps = getDefaultVisualizationTogglePropsBuilder()
- .with('checked', false)
- .with('disabled', false)
- .build();
+ expect(textDiv.exists()).toBeTruthy();
+ expect(textDiv.childAt(0).text()).toEqual(visualHelperText);
+ expect(testSubject.find('strong').exists()).toBeFalsy();
+ }
- assertVisualizationToggle(expectedToggleProps, toggle);
- });
+ function expectDisabledTextLayout(
+ testSubject: Enzyme.ShallowWrapper,
+ ): void {
+ const visualHelperClass = 'visual-helper';
+ const toggleDiv = testSubject.find(`.${visualHelperClass}`);
+
+ expect(toggleDiv.exists()).toBeTruthy();
- it('enables all visualizations when none are shown', () => {
- const props = new VisualHelperToggleConfigBuilder()
- .withToggleStepEnabled(true)
- .withToggleStepScanned(false)
- .withActionMessageCreator(actionMessageCreatorMock.object)
- .build();
-
- const wrapper = Enzyme.shallow();
- actionMessageCreatorMock.reset();
- actionMessageCreatorMock
- .setup(acm =>
- acm.changeAssessmentVisualizationStateForAll(
- true,
- props.assessmentNavState.selectedTestType,
- props.assessmentNavState.selectedTestSubview,
- ),
- )
- .verifiable(Times.once());
-
- wrapper.find(VisualizationToggle).simulate('click');
-
- actionMessageCreatorMock.verifyAll();
+ const textDiv = toggleDiv.find(`.${visualHelperClass}-text`);
+
+ expect(textDiv.exists()).toBeTruthy();
+ expect(textDiv.childAt(0).text()).toEqual(visualHelperText);
+
+ const noMatchesWarningClass = 'no-matching-elements';
+ expect(testSubject.find(`.${noMatchesWarningClass}`).exists()).toBeTruthy();
+ }
});
- it('disables all visualizations when some are shown', () => {
- const props = new VisualHelperToggleConfigBuilder()
- .withToggleStepEnabled(true)
- .withToggleStepScanned(false)
- .withActionMessageCreator(actionMessageCreatorMock.object)
- .withNonEmptyFilteredMap(true)
- .build();
-
- const wrapper = Enzyme.shallow();
- actionMessageCreatorMock.reset();
- actionMessageCreatorMock
- .setup(acm =>
- acm.changeAssessmentVisualizationStateForAll(
- false,
- props.assessmentNavState.selectedTestType,
- props.assessmentNavState.selectedTestSubview,
- ),
- )
- .verifiable(Times.once());
-
- wrapper.find(VisualizationToggle).simulate('click');
-
- actionMessageCreatorMock.verifyAll();
+ describe('toggle behavior', () => {
+ it('enables all visualizations when none are shown', () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(true)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .build();
+
+ const wrapper = Enzyme.shallow();
+ actionMessageCreatorMock.reset();
+ actionMessageCreatorMock
+ .setup(acm =>
+ acm.changeAssessmentVisualizationStateForAll(
+ true,
+ props.assessmentNavState.selectedTestType,
+ props.assessmentNavState.selectedTestSubview,
+ ),
+ )
+ .verifiable(Times.once());
+
+ wrapper.find(VisualizationToggle).simulate('click');
+
+ actionMessageCreatorMock.verifyAll();
+ });
+
+ it('disables all visualizations when some are shown', () => {
+ const props = new VisualHelperToggleConfigBuilder()
+ .withToggleStepEnabled(true)
+ .withToggleStepScanned(false)
+ .withActionMessageCreator(actionMessageCreatorMock.object)
+ .withNonEmptyFilteredMap(true)
+ .build();
+
+ const wrapper = Enzyme.shallow();
+ actionMessageCreatorMock.reset();
+ actionMessageCreatorMock
+ .setup(acm =>
+ acm.changeAssessmentVisualizationStateForAll(
+ false,
+ props.assessmentNavState.selectedTestType,
+ props.assessmentNavState.selectedTestSubview,
+ ),
+ )
+ .verifiable(Times.once());
+
+ wrapper.find(VisualizationToggle).simulate('click');
+
+ actionMessageCreatorMock.verifyAll();
+ });
});
- function assertVisualizationToggle(
+ function expectChildVisualizationToggleWith(
expectedProps: VisualizationToggleProps,
- visualizationToggle: Enzyme.ShallowWrapper,
+ testSubject: Enzyme.ShallowWrapper,
): void {
+ const visualizationToggle = testSubject.find(VisualizationToggle);
+
expect(visualizationToggle.exists()).toBeTruthy();
const actualProps = visualizationToggle.props();
diff --git a/src/tests/unit/tests/assessments/landmarks/auto-pass-if-no-landmarks.test.ts b/src/tests/unit/tests/assessments/landmarks/auto-pass-if-no-landmarks.test.ts
new file mode 100644
index 00000000000..ece051ee4ac
--- /dev/null
+++ b/src/tests/unit/tests/assessments/landmarks/auto-pass-if-no-landmarks.test.ts
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import { autoPassIfNoLandmarks } from 'assessments/landmarks/auto-pass-if-no-landmarks';
+import { ManualTestStatus } from 'common/types/manual-test-status';
+import { InstanceIdToInstanceDataMap } from 'common/types/store-data/assessment-result-data';
+
+describe('autoPassIfNoLandmarks', () => {
+ it('returns PASS for instance data with no landmarks', () => {
+ const input = makeInputDataWithLandmarkRoles([]);
+ expect(autoPassIfNoLandmarks(input)).toBe(ManualTestStatus.PASS);
+ });
+
+ it.each(['main', 'complementary'])(
+ 'returns UNKNOWN for instance data with one %s landmark',
+ (landmarkRole: string) => {
+ const input = makeInputDataWithLandmarkRoles([landmarkRole]);
+ expect(autoPassIfNoLandmarks(input)).toBe(ManualTestStatus.UNKNOWN);
+ },
+ );
+
+ it('returns UNKNOWN for instance data with multiple landmarks', () => {
+ const input = makeInputDataWithLandmarkRoles(['main', 'complementary', 'header']);
+ expect(autoPassIfNoLandmarks(input)).toBe(ManualTestStatus.UNKNOWN);
+ });
+
+ function makeInputDataWithLandmarkRoles(landmarkRoles: string[]): InstanceIdToInstanceDataMap {
+ const data: InstanceIdToInstanceDataMap = {};
+ for (const landmarkRole of landmarkRoles) {
+ data[`#element-with-${landmarkRole}`] = {
+ target: [`#element-with-${landmarkRole}`],
+ html: ``,
+ propertyBag: {
+ role: landmarkRole,
+ },
+ testStepResults: {},
+ };
+ }
+ return data;
+ }
+});
diff --git a/src/tests/unit/tests/assessments/landmarks/does-result-have-main-role.test.ts b/src/tests/unit/tests/assessments/landmarks/does-result-have-main-role.test.ts
new file mode 100644
index 00000000000..83295474935
--- /dev/null
+++ b/src/tests/unit/tests/assessments/landmarks/does-result-have-main-role.test.ts
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import { doesResultHaveMainRole } from 'assessments/landmarks/does-result-have-main-role';
+import { DecoratedAxeNodeResult } from 'injected/scanner-utils';
+
+describe('doesResultHaveMainRole', () => {
+ it('returns false for results with no check results', () => {
+ const input = { any: [], all: [] } as DecoratedAxeNodeResult;
+
+ expect(doesResultHaveMainRole(input)).toBe(false);
+ });
+
+ it('returns false for results with check results without role data', () => {
+ const input = {
+ any: [makeCheckResultWithRole(undefined)],
+ all: [makeCheckResultWithRole(undefined)],
+ } as DecoratedAxeNodeResult;
+
+ expect(doesResultHaveMainRole(input)).toBe(false);
+ });
+
+ it('returns false for results with check results with only non-main role data', () => {
+ const input = {
+ any: [makeCheckResultWithRole('complementary')],
+ all: [makeCheckResultWithRole('banner')],
+ } as DecoratedAxeNodeResult;
+
+ expect(doesResultHaveMainRole(input)).toBe(false);
+ });
+
+ it('returns true for results with an "any" check result with "main" role data', () => {
+ const input = {
+ any: [makeCheckResultWithRole('main')],
+ all: [],
+ } as DecoratedAxeNodeResult;
+
+ expect(doesResultHaveMainRole(input)).toBe(true);
+ });
+
+ it('returns true for results with an "all" check result with "main" role data', () => {
+ const input = {
+ any: [],
+ all: [makeCheckResultWithRole('main')],
+ } as DecoratedAxeNodeResult;
+
+ expect(doesResultHaveMainRole(input)).toBe(true);
+ });
+
+ it('returns true for results with mixed check results', () => {
+ const input = {
+ any: [makeCheckResultWithRole('banner'), makeCheckResultWithRole(undefined)],
+ all: [
+ makeCheckResultWithRole('main'),
+ makeCheckResultWithRole('banner'),
+ makeCheckResultWithRole(undefined),
+ ],
+ } as DecoratedAxeNodeResult;
+
+ expect(doesResultHaveMainRole(input)).toBe(true);
+ });
+
+ function makeCheckResultWithRole(role: string): FormattedCheckResult {
+ return {
+ id: 'test-check-id',
+ message: 'test check message',
+ data: {
+ role,
+ },
+ };
+ }
+});
diff --git a/src/tests/unit/tests/background/assessment-data-converter.test.ts b/src/tests/unit/tests/background/assessment-data-converter.test.ts
index c87b86145f7..911c9c97f5f 100644
--- a/src/tests/unit/tests/background/assessment-data-converter.test.ts
+++ b/src/tests/unit/tests/background/assessment-data-converter.test.ts
@@ -13,7 +13,7 @@ import { DecoratedAxeNodeResult, HtmlElementAxeResults } from '../../../../injec
import { TabStopEvent } from '../../../../injected/tab-stops-listener';
import { DictionaryStringTo } from '../../../../types/common-types';
-describe('AssessmentDataConverterTest', () => {
+describe('AssessmentDataConverter', () => {
let testSubject: AssessmentDataConverter;
const uid: string = 'uid123';
let testStep: string;
@@ -22,6 +22,7 @@ describe('AssessmentDataConverterTest', () => {
status: ManualTestStatus.UNKNOWN,
isCapturedByUser: false,
failureSummary: null,
+ isVisualizationSupported: true,
isVisualizationEnabled: true,
isVisible: true,
};
@@ -39,305 +40,285 @@ describe('AssessmentDataConverterTest', () => {
htmlStub = 'some html';
});
- test('generateAssessmentInstancesMap: property bag from any checks', () => {
- const expectedPropertyBag = {
- someProperty: 1,
- };
-
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {
- rule1: {
- any: [
- {
- id: 'rule1',
- data: expectedPropertyBag,
- },
- ],
- html: htmlStub,
- id: 'id1',
- status: true,
- } as DecoratedAxeNodeResult,
+ describe('generateAssessmentInstancesMap', () => {
+ it('should ignore selectors with no rule results.', () => {
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {},
+ target: [selectorStub],
},
- target: [selectorStub],
- },
- };
-
- setupGenerateInstanceIdentifierMock(
- { target: [selectorStub], html: htmlStub },
- identifierStub,
- );
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- null,
- selectorMap,
- testStep,
- generateInstanceIdentifierMock.object,
- () => ManualTestStatus.UNKNOWN,
- );
-
- expect(instanceMap[identifierStub].propertyBag).toEqual(expectedPropertyBag);
- });
-
- test(`generateAssessmentInstancesMap: previouslyGeneratedInstances is null,
- new rule result is not false and any data is there.`, () => {
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {
- rule1: {
- any: [
- {
- id: 'rule1',
- data: { someProperty: 1 },
- },
- ],
- html: htmlStub,
- id: 'id1',
- status: true,
- } as DecoratedAxeNodeResult,
+ };
+ const previouslyGeneratedInstances = {};
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ previouslyGeneratedInstances,
+ selectorMap,
+ testStep,
+ undefined,
+ null,
+ null,
+ );
+
+ expect(instanceMap).toEqual(previouslyGeneratedInstances);
+ });
+
+ it('should produce an empty map (not null) if previouslyGeneratedInstances is null and there are no rule results to add', () => {
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {},
+ target: [selectorStub],
},
- target: [selectorStub],
- },
- };
- const expectedResult = {
- [identifierStub]: {
- html: htmlStub,
- propertyBag: { someProperty: 1 },
- target: [selectorStub],
- testStepResults: {
- [testStep]: {
- id: 'id1',
- status: ManualTestStatus.UNKNOWN,
- isCapturedByUser: false,
- failureSummary: undefined,
- isVisible: true,
- isVisualizationEnabled: false,
+ };
+ const expectedResult = {};
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ null,
+ selectorMap,
+ testStep,
+ undefined,
+ null,
+ null,
+ );
+
+ expect(instanceMap).toEqual(expectedResult);
+ });
+
+ it('should create a new instance wrapping the generated result if there is no existing instance matching the selector', () => {
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {
+ rule1: {
+ html: htmlStub,
+ id: 'id1',
+ status: false,
+ } as DecoratedAxeNodeResult,
},
+ target: [selectorStub],
},
- },
- };
-
- setupGenerateInstanceIdentifierMock(
- { target: [selectorStub], html: htmlStub },
- identifierStub,
- );
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- null,
- selectorMap,
- testStep,
- generateInstanceIdentifierMock.object,
- () => ManualTestStatus.UNKNOWN,
- );
-
- expect(instanceMap).toEqual(expectedResult);
- });
-
- test(`generateAssessmentInstancesMap: previouslyGeneratedInstances is null,
- new rule result is null (shouldn't happen but covered).`, () => {
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {},
- target: [selectorStub],
- },
- };
- const expectedResult = {};
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- null,
- selectorMap,
- testStep,
- undefined,
- null,
- );
-
- expect(instanceMap).toEqual(expectedResult);
- });
-
- test(`generateAssessmentInstancesMap: previouslyGeneratedInstances is not null,
- new rule result is null (shouldn't happen but covered).`, () => {
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {},
- target: [selectorStub],
- },
- };
- const previouslyGeneratedInstances = {};
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- previouslyGeneratedInstances,
- selectorMap,
- testStep,
- undefined,
- null,
- );
-
- expect(instanceMap).toEqual(previouslyGeneratedInstances);
- });
-
- test(`generateAssessmentInstancesMap: previouslyGeneratedInstances is
- empty/does not match any new instances and any data is not there`, () => {
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {
- rule1: {
- html: htmlStub,
- id: 'id1',
- status: false,
- } as DecoratedAxeNodeResult,
+ };
+ const expectedResult = {
+ [identifierStub]: {
+ html: htmlStub,
+ propertyBag: null,
+ target: [selectorStub],
+ testStepResults: {
+ [testStep]: {
+ id: 'id1',
+ status: ManualTestStatus.UNKNOWN,
+ isCapturedByUser: false,
+ failureSummary: undefined,
+ isVisible: true,
+ isVisualizationEnabled: false,
+ isVisualizationSupported: true,
+ },
+ },
},
- target: [selectorStub],
- },
- };
- const expectedResult = {
- [identifierStub]: {
- html: htmlStub,
- propertyBag: null,
- target: [selectorStub],
- testStepResults: {
- [testStep]: {
- id: 'id1',
- status: ManualTestStatus.UNKNOWN,
- isCapturedByUser: false,
- failureSummary: undefined,
- isVisible: true,
- isVisualizationEnabled: false,
+ };
+ setupGenerateInstanceIdentifierMock(
+ { target: [selectorStub], html: htmlStub },
+ identifierStub,
+ );
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ {},
+ selectorMap,
+ testStep,
+ generateInstanceIdentifierMock.object,
+ () => ManualTestStatus.UNKNOWN,
+ () => true,
+ );
+
+ expect(instanceMap).toEqual(expectedResult);
+ });
+
+ it("should merge check results' data into the instance's propertyBag", () => {
+ const expectedPropertyBag = {
+ someProperty: 1,
+ };
+
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {
+ rule1: {
+ any: [
+ {
+ id: 'rule1',
+ data: expectedPropertyBag,
+ },
+ ],
+ html: htmlStub,
+ id: 'id1',
+ status: true,
+ } as DecoratedAxeNodeResult,
},
+ target: [selectorStub],
},
+ };
+
+ setupGenerateInstanceIdentifierMock(
+ { target: [selectorStub], html: htmlStub },
+ identifierStub,
+ );
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ null,
+ selectorMap,
+ testStep,
+ generateInstanceIdentifierMock.object,
+ () => ManualTestStatus.UNKNOWN,
+ () => true,
+ );
+
+ expect(instanceMap[identifierStub].propertyBag).toEqual(expectedPropertyBag);
+ });
+
+ it.each([ManualTestStatus.FAIL, ManualTestStatus.UNKNOWN, ManualTestStatus.PASS])(
+ 'should use getInstanceStatus to determine the status of the generated step result',
+ (getInstanceStatusResult: ManualTestStatus) => {
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {
+ rule1: {
+ html: htmlStub,
+ id: 'id1',
+ status: false,
+ } as DecoratedAxeNodeResult,
+ },
+ target: [selectorStub],
+ },
+ };
+
+ setupGenerateInstanceIdentifierMock(
+ { target: [selectorStub], html: htmlStub },
+ identifierStub,
+ );
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ {},
+ selectorMap,
+ testStep,
+ generateInstanceIdentifierMock.object,
+ () => getInstanceStatusResult,
+ () => true,
+ );
+
+ expect(instanceMap[identifierStub].testStepResults[testStep].status).toEqual(
+ getInstanceStatusResult,
+ );
},
- };
- setupGenerateInstanceIdentifierMock(
- { target: [selectorStub], html: htmlStub },
- identifierStub,
- );
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- {},
- selectorMap,
- testStep,
- generateInstanceIdentifierMock.object,
- () => ManualTestStatus.UNKNOWN,
);
- expect(instanceMap).toEqual(expectedResult);
- });
-
- test('generateAssessmentInstancesMap: automated check status should be FAIL', () => {
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {
- rule1: {
- html: htmlStub,
- id: 'id1',
- status: false,
- } as DecoratedAxeNodeResult,
- },
- target: [selectorStub],
- },
- };
- const expectedResult = {
- [identifierStub]: {
- html: htmlStub,
- propertyBag: null,
- target: [selectorStub],
- testStepResults: {
- [testStep]: {
- id: 'id1',
- status: ManualTestStatus.FAIL,
- isCapturedByUser: false,
- failureSummary: undefined,
- isVisible: true,
- isVisualizationEnabled: false,
+ it.each([true, false])(
+ 'should use isVisualizationSupported to determine the corresponding property of the generated step result',
+ (isVisualizationSupportedResult: boolean) => {
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {
+ rule1: {
+ html: htmlStub,
+ id: 'id1',
+ status: false,
+ } as DecoratedAxeNodeResult,
+ },
+ target: [selectorStub],
},
- },
+ };
+
+ setupGenerateInstanceIdentifierMock(
+ { target: [selectorStub], html: htmlStub },
+ identifierStub,
+ );
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ {},
+ selectorMap,
+ testStep,
+ generateInstanceIdentifierMock.object,
+ () => ManualTestStatus.UNKNOWN,
+ () => isVisualizationSupportedResult,
+ );
+
+ expect(
+ instanceMap[identifierStub].testStepResults[testStep].isVisualizationSupported,
+ ).toEqual(isVisualizationSupportedResult);
},
- };
- setupGenerateInstanceIdentifierMock(
- { target: [selectorStub], html: htmlStub },
- identifierStub,
);
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- {},
- selectorMap,
- testStep,
- generateInstanceIdentifierMock.object,
- () => ManualTestStatus.FAIL,
- );
-
- expect(instanceMap).toEqual(expectedResult);
- });
- test('generateAssessmentInstancesMap: previouslyGeneratedInstances contains matching instance', () => {
- const anotherTestStep = 'another test step';
- const selectorMap: DictionaryStringTo = {
- [selectorStub]: {
- ruleResults: {
- rule1: {
- any: [
- {
- id: 'rule1',
- data: { someProperty: 1 },
- },
- ],
- html: htmlStub,
- id: 'id1',
- status: false,
- } as DecoratedAxeNodeResult,
- },
- target: [selectorStub],
- },
- };
- const previouslyGeneratedInstances: AssessmentInstancesMap = {
- [identifierStub]: {
- html: htmlStub,
- propertyBag: { someProperty: 3 },
- target: [selectorStub],
- testStepResults: {
- [anotherTestStep]: {
- id: 'id2',
- status: ManualTestStatus.UNKNOWN,
- isCapturedByUser: false,
- failureSummary: undefined,
- isVisible: true,
- isVisualizationEnabled: true,
+ it('should merge results for a previously seen selector into the existing instance data', () => {
+ const anotherTestStep = 'another test step';
+ const selectorMap: DictionaryStringTo = {
+ [selectorStub]: {
+ ruleResults: {
+ rule1: {
+ any: [
+ {
+ id: 'rule1',
+ data: { someProperty: 1 },
+ },
+ ],
+ html: htmlStub,
+ id: 'id1',
+ status: false,
+ } as DecoratedAxeNodeResult,
},
+ target: [selectorStub],
},
- },
- };
- const expectedResult = {
- [identifierStub]: {
- html: htmlStub,
- propertyBag: { someProperty: 3 },
- target: [selectorStub],
- testStepResults: {
- [testStep]: {
- id: 'id1',
- status: ManualTestStatus.UNKNOWN,
- isCapturedByUser: false,
- failureSummary: undefined,
- isVisible: true,
- isVisualizationEnabled: false,
+ };
+ const previouslyGeneratedInstances: AssessmentInstancesMap = {
+ [identifierStub]: {
+ html: htmlStub,
+ propertyBag: { someProperty: 3 },
+ target: [selectorStub],
+ testStepResults: {
+ [anotherTestStep]: {
+ id: 'id2',
+ status: ManualTestStatus.UNKNOWN,
+ isCapturedByUser: false,
+ failureSummary: undefined,
+ isVisible: true,
+ isVisualizationEnabled: true,
+ isVisualizationSupported: true,
+ },
},
- [anotherTestStep]: {
- id: 'id2',
- status: ManualTestStatus.UNKNOWN,
- isCapturedByUser: false,
- failureSummary: undefined,
- isVisible: true,
- isVisualizationEnabled: true,
+ },
+ };
+ const expectedResult = {
+ [identifierStub]: {
+ html: htmlStub,
+ propertyBag: { someProperty: 3 },
+ target: [selectorStub],
+ testStepResults: {
+ [testStep]: {
+ id: 'id1',
+ status: ManualTestStatus.UNKNOWN,
+ isCapturedByUser: false,
+ failureSummary: undefined,
+ isVisible: true,
+ isVisualizationEnabled: false,
+ isVisualizationSupported: true,
+ },
+ [anotherTestStep]: {
+ id: 'id2',
+ status: ManualTestStatus.UNKNOWN,
+ isCapturedByUser: false,
+ failureSummary: undefined,
+ isVisible: true,
+ isVisualizationEnabled: true,
+ isVisualizationSupported: true,
+ },
},
},
- },
- };
-
- setupGenerateInstanceIdentifierMock(
- { target: [selectorStub], html: htmlStub },
- identifierStub,
- );
- const instanceMap = testSubject.generateAssessmentInstancesMap(
- previouslyGeneratedInstances,
- selectorMap,
- testStep,
- generateInstanceIdentifierMock.object,
- () => ManualTestStatus.UNKNOWN,
- );
-
- expect(instanceMap).toEqual(expectedResult);
+ };
+
+ setupGenerateInstanceIdentifierMock(
+ { target: [selectorStub], html: htmlStub },
+ identifierStub,
+ );
+ const instanceMap = testSubject.generateAssessmentInstancesMap(
+ previouslyGeneratedInstances,
+ selectorMap,
+ testStep,
+ generateInstanceIdentifierMock.object,
+ () => ManualTestStatus.UNKNOWN,
+ () => true,
+ );
+
+ expect(instanceMap).toEqual(expectedResult);
+ });
});
test('generateAssessmentInstancesMapForEvents: previouslyGeneratedInstances is null', () => {
diff --git a/src/tests/unit/tests/background/stores/__snapshots__/assessment-store.test.ts.snap b/src/tests/unit/tests/background/stores/__snapshots__/assessment-store.test.ts.snap
index 7c92b440b56..217f5139508 100644
--- a/src/tests/unit/tests/background/stores/__snapshots__/assessment-store.test.ts.snap
+++ b/src/tests/unit/tests/background/stores/__snapshots__/assessment-store.test.ts.snap
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`AssessmentStoreTest onResetAllAssessmentsData 1`] = `"tab with Id 1000 not found"`;
+exports[`AssessmentStore onResetAllAssessmentsData 1`] = `"tab with Id 1000 not found"`;
-exports[`AssessmentStoreTest onUpdateTargetTabId 1`] = `"tab with Id 1000 not found"`;
+exports[`AssessmentStore onUpdateTargetTabId 1`] = `"tab with Id 1000 not found"`;
diff --git a/src/tests/unit/tests/background/stores/assessment-store.test.ts b/src/tests/unit/tests/background/stores/assessment-store.test.ts
index f87c17fad8a..39776f31617 100644
--- a/src/tests/unit/tests/background/stores/assessment-store.test.ts
+++ b/src/tests/unit/tests/background/stores/assessment-store.test.ts
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
import { AssessmentsProvider } from 'assessments/types/assessments-provider';
import { Assessment } from 'assessments/types/iassessment';
+import { Requirement } from 'assessments/types/requirement';
import {
AddFailureInstancePayload,
AddResultDescriptionPayload,
@@ -59,7 +60,7 @@ const assessmentKey: string = 'assessment-1';
const requirementKey: string = 'assessment-1-step-1';
const assessmentType = -1 as VisualizationType;
-describe('AssessmentStoreTest', () => {
+describe('AssessmentStore', () => {
let browserMock: IMock;
let assessmentDataConverterMock: IMock;
let assessmentDataRemoverMock: IMock;
@@ -470,7 +471,7 @@ describe('AssessmentStoreTest', () => {
.testListenerToBeCalledOnce(initialState, finalState);
});
- test('onScanCompleted', () => {
+ test('onScanCompleted with an assisted requirement', () => {
const initialAssessmentData = new AssessmentDataBuilder()
.with('testStepStatus', {
['assessment-1-step-1']: getDefaultTestStepData(),
@@ -490,16 +491,121 @@ describe('AssessmentStoreTest', () => {
const expectedInstanceMap = {};
const stepMapStub = assessmentsProvider.getStepMap(assessmentType);
- const stepConfig = assessmentsProvider.getStep(assessmentType, 'assessment-1-step-1');
+ const stepConfig: Readonly = {
+ ...assessmentsProvider.getStep(assessmentType, 'assessment-1-step-1'),
+ isManual: false,
+ };
const assessmentData = new AssessmentDataBuilder()
.with('generatedAssessmentInstancesMap', expectedInstanceMap)
.with('testStepStatus', {
+ // should PASS because it is a non-manual test with no associated instances
['assessment-1-step-1']: generateTestStepData(ManualTestStatus.PASS, true),
+ // should stay unchanged because the event/payload is requirement-specific
+ ['assessment-1-step-2']: getDefaultTestStepData(),
+ ['assessment-1-step-3']: getDefaultTestStepData(),
+ })
+ .with('scanIncompleteWarnings', [])
+ .build();
+
+ const finalState = getStateWithAssessment(assessmentData);
+
+ assessmentsProviderMock
+ .setup(provider => provider.all())
+ .returns(() => assessmentsProvider.all());
+
+ assessmentsProviderMock
+ .setup(provider => provider.getStepMap(assessmentType))
+ .returns(() => stepMapStub);
+
+ assessmentsProviderMock
+ .setup(provider => provider.getStep(assessmentType, 'assessment-1-step-1'))
+ .returns(() => stepConfig);
+
+ assessmentsProviderMock
+ .setup(provider => provider.forType(payload.testType))
+ .returns(() => assessmentMock.object);
+
+ assessmentMock.setup(am => am.getVisualizationConfiguration()).returns(() => configStub);
+
+ getInstanceIdentiferGeneratorMock
+ .setup(idGetter => idGetter(requirementKey))
+ .returns(() => instanceIdentifierGeneratorStub);
+
+ assessmentDataConverterMock
+ .setup(a =>
+ a.generateAssessmentInstancesMap(
+ initialAssessmentData.generatedAssessmentInstancesMap,
+ payload.selectorMap,
+ requirementKey,
+ instanceIdentifierGeneratorStub,
+ stepConfig.getInstanceStatus,
+ stepConfig.isVisualizationSupportedForResult,
+ ),
+ )
+ .returns(() => expectedInstanceMap);
+
+ createStoreTesterForAssessmentActions('scanCompleted')
+ .withActionParam(payload)
+ .testListenerToBeCalledOnce(initialState, finalState);
+ });
+
+ test('onScanCompleted with a manual requirement uses getInitialManualTestStatus to set status', () => {
+ const initialManualTestStepResult = {
+ status: ManualTestStatus.UNKNOWN,
+ id: requirementKey,
+ instances: [
+ {
+ id: '1',
+ description: 'aaa',
+ },
+ ],
+ };
+ const initialAssessmentData = new AssessmentDataBuilder()
+ .with('testStepStatus', {
+ ['assessment-1-step-1']: getDefaultTestStepData(),
+ ['assessment-1-step-2']: getDefaultTestStepData(),
+ ['assessment-1-step-3']: getDefaultTestStepData(),
+ })
+ .with('manualTestStepResultMap', {
+ [requirementKey]: initialManualTestStepResult,
+ })
+ .build();
+ const initialState = getStateWithAssessment(initialAssessmentData);
+
+ const payload: ScanCompletedPayload = {
+ selectorMap: {},
+ scanResult: {} as ScanResults,
+ testType: assessmentType,
+ key: requirementKey,
+ scanIncompleteWarnings: [],
+ };
+
+ const expectedInstanceMap = {};
+ const stepMapStub = assessmentsProvider.getStepMap(assessmentType);
+ const stepConfig: Readonly = {
+ ...assessmentsProvider.getStep(assessmentType, 'assessment-1-step-1'),
+ isManual: true,
+ getInitialManualTestStatus: () => ManualTestStatus.FAIL,
+ };
+
+ const assessmentData = new AssessmentDataBuilder()
+ .with('generatedAssessmentInstancesMap', expectedInstanceMap)
+ .with('testStepStatus', {
+ // should FAIL based on getInitialManualTestStatus
+ ['assessment-1-step-1']: generateTestStepData(ManualTestStatus.FAIL, true),
+ // should stay unchanged because the event/payload is requirement-specific
['assessment-1-step-2']: getDefaultTestStepData(),
['assessment-1-step-3']: getDefaultTestStepData(),
})
.with('scanIncompleteWarnings', [])
+ .with('manualTestStepResultMap', {
+ [requirementKey]: {
+ ...initialManualTestStepResult,
+ // should FAIL based on getInitialManualTestStatus
+ status: ManualTestStatus.FAIL,
+ },
+ })
.build();
const finalState = getStateWithAssessment(assessmentData);
@@ -533,7 +639,108 @@ describe('AssessmentStoreTest', () => {
payload.selectorMap,
requirementKey,
instanceIdentifierGeneratorStub,
- It.isAny(),
+ stepConfig.getInstanceStatus,
+ stepConfig.isVisualizationSupportedForResult,
+ ),
+ )
+ .returns(() => expectedInstanceMap);
+
+ createStoreTesterForAssessmentActions('scanCompleted')
+ .withActionParam(payload)
+ .testListenerToBeCalledOnce(initialState, finalState);
+ });
+
+ test('onScanCompleted with a manual requirement skips getInitialManualTestStatus for requirements that already have a status', () => {
+ const initialManualTestStepResult = {
+ status: ManualTestStatus.PASS,
+ id: requirementKey,
+ instances: [
+ {
+ id: '1',
+ description: 'aaa',
+ },
+ ],
+ };
+ const initialAssessmentData = new AssessmentDataBuilder()
+ .with('testStepStatus', {
+ ['assessment-1-step-1']: generateTestStepData(ManualTestStatus.PASS, true),
+ ['assessment-1-step-2']: getDefaultTestStepData(),
+ ['assessment-1-step-3']: getDefaultTestStepData(),
+ })
+ .with('manualTestStepResultMap', {
+ [requirementKey]: initialManualTestStepResult,
+ })
+ .build();
+ const initialState = getStateWithAssessment(initialAssessmentData);
+
+ const payload: ScanCompletedPayload = {
+ selectorMap: {},
+ scanResult: {} as ScanResults,
+ testType: assessmentType,
+ key: requirementKey,
+ scanIncompleteWarnings: [],
+ };
+
+ const expectedInstanceMap = {};
+ const stepMapStub = assessmentsProvider.getStepMap(assessmentType);
+ const stepConfig: Readonly = {
+ ...assessmentsProvider.getStep(assessmentType, 'assessment-1-step-1'),
+ isManual: true,
+ getInitialManualTestStatus: () => ManualTestStatus.FAIL,
+ };
+
+ const assessmentData = new AssessmentDataBuilder()
+ .with('generatedAssessmentInstancesMap', expectedInstanceMap)
+ .with('testStepStatus', {
+ // should ignore getInitialManualTestStatus because the original state was not UNKNOWN
+ ['assessment-1-step-1']: generateTestStepData(ManualTestStatus.PASS, true),
+ // should stay unchanged because the event/payload is requirement-specific
+ ['assessment-1-step-2']: getDefaultTestStepData(),
+ ['assessment-1-step-3']: getDefaultTestStepData(),
+ })
+ .with('scanIncompleteWarnings', [])
+ .with('manualTestStepResultMap', {
+ [requirementKey]: {
+ ...initialManualTestStepResult,
+ // should ignore getInitialManualTestStatus because the original state was not UNKNOWN
+ status: ManualTestStatus.PASS,
+ },
+ })
+ .build();
+
+ const finalState = getStateWithAssessment(assessmentData);
+
+ assessmentsProviderMock
+ .setup(provider => provider.all())
+ .returns(() => assessmentsProvider.all());
+
+ assessmentsProviderMock
+ .setup(provider => provider.getStepMap(assessmentType))
+ .returns(() => stepMapStub);
+
+ assessmentsProviderMock
+ .setup(provider => provider.getStep(assessmentType, 'assessment-1-step-1'))
+ .returns(() => stepConfig);
+
+ assessmentsProviderMock
+ .setup(provider => provider.forType(payload.testType))
+ .returns(() => assessmentMock.object);
+
+ assessmentMock.setup(am => am.getVisualizationConfiguration()).returns(() => configStub);
+
+ getInstanceIdentiferGeneratorMock
+ .setup(idGetter => idGetter(requirementKey))
+ .returns(() => instanceIdentifierGeneratorStub);
+
+ assessmentDataConverterMock
+ .setup(a =>
+ a.generateAssessmentInstancesMap(
+ initialAssessmentData.generatedAssessmentInstancesMap,
+ payload.selectorMap,
+ requirementKey,
+ instanceIdentifierGeneratorStub,
+ stepConfig.getInstanceStatus,
+ stepConfig.isVisualizationSupportedForResult,
),
)
.returns(() => expectedInstanceMap);
@@ -893,56 +1100,73 @@ describe('AssessmentStoreTest', () => {
.testListenerToBeCalledOnce(initialState, finalState);
});
- test('on changeAssessmentVisualizationState', () => {
- const generatedAssessmentInstancesMap: DictionaryStringTo = {
- selector: {
- testStepResults: {
- [requirementKey]: {
- isVisualizationEnabled: true,
+ test.each`
+ supportsVisualization | startsEnabled | payloadEnabled | expectedFinalEnabled
+ ${false} | ${false} | ${true} | ${false}
+ ${true} | ${false} | ${true} | ${true}
+ ${true} | ${true} | ${false} | ${false}
+ ${true} | ${true} | ${true} | ${true}
+ ${true} | ${false} | ${false} | ${false}
+ `(
+ 'on changeAssessmentVisualizationState: supportsVisualization:$supportsVisualization, ' +
+ 'startsEnabled:$startsEnabled, payloadEnabled:$payloadEnabled -> finalEnabled:$expectedFinalEnabled',
+ ({ supportsVisualization, startsEnabled, payloadEnabled, expectedFinalEnabled }) => {
+ const generatedAssessmentInstancesMap: DictionaryStringTo = {
+ selector: {
+ testStepResults: {
+ [requirementKey]: {
+ isVisualizationEnabled: startsEnabled,
+ isVisualizationSupported: supportsVisualization,
+ },
},
- },
- } as any,
- };
+ } as any,
+ };
- const assessmentData = new AssessmentDataBuilder()
- .with('generatedAssessmentInstancesMap', generatedAssessmentInstancesMap)
- .build();
+ const assessmentData = new AssessmentDataBuilder()
+ .with('generatedAssessmentInstancesMap', generatedAssessmentInstancesMap)
+ .build();
- const initialState = getStateWithAssessment(assessmentData);
+ const initialState = getStateWithAssessment(assessmentData);
- const payload: ChangeInstanceSelectionPayload = {
- test: assessmentType,
- requirement: requirementKey,
- isVisualizationEnabled: true,
- selector: 'selector',
- };
+ const payload: ChangeInstanceSelectionPayload = {
+ test: assessmentType,
+ requirement: requirementKey,
+ isVisualizationEnabled: payloadEnabled,
+ selector: 'selector',
+ };
- assessmentsProviderMock
- .setup(apm => apm.forType(payload.test))
- .returns(() => assessmentMock.object);
+ assessmentsProviderMock
+ .setup(apm => apm.forType(payload.test))
+ .returns(() => assessmentMock.object);
- assessmentMock.setup(am => am.getVisualizationConfiguration()).returns(() => configStub);
+ assessmentMock
+ .setup(am => am.getVisualizationConfiguration())
+ .returns(() => configStub);
- const expectedInstancesMap = cloneDeep(generatedAssessmentInstancesMap);
- expectedInstancesMap.selector.testStepResults[requirementKey].isVisualizationEnabled = true;
+ const expectedInstancesMap = cloneDeep(generatedAssessmentInstancesMap);
+ expectedInstancesMap.selector.testStepResults[
+ requirementKey
+ ].isVisualizationEnabled = expectedFinalEnabled;
- const expectedAssessment = new AssessmentDataBuilder()
- .with('generatedAssessmentInstancesMap', expectedInstancesMap)
- .build();
+ const expectedAssessment = new AssessmentDataBuilder()
+ .with('generatedAssessmentInstancesMap', expectedInstancesMap)
+ .build();
- const finalState = getStateWithAssessment(expectedAssessment);
+ const finalState = getStateWithAssessment(expectedAssessment);
- createStoreTesterForAssessmentActions('changeAssessmentVisualizationState')
- .withActionParam(payload)
- .testListenerToBeCalledOnce(initialState, finalState);
- });
+ createStoreTesterForAssessmentActions('changeAssessmentVisualizationState')
+ .withActionParam(payload)
+ .testListenerToBeCalledOnce(initialState, finalState);
+ },
+ );
- test('on changeAssessmentVisualizationStateForAll', () => {
+ test('changeAssessmentVisualizationStateForAll enables all visualizations that support it', () => {
const generatedAssessmentInstancesMap: DictionaryStringTo = {
selector1: {
testStepResults: {
[requirementKey]: {
isVisualizationEnabled: true,
+ isVisualizationSupported: true,
},
},
} as any,
@@ -950,12 +1174,21 @@ describe('AssessmentStoreTest', () => {
testStepResults: {
[requirementKey]: {
isVisualizationEnabled: false,
+ isVisualizationSupported: false,
},
},
} as any,
selector3: {
testStepResults: {},
} as any,
+ selector4: {
+ testStepResults: {
+ [requirementKey]: {
+ isVisualizationEnabled: false,
+ isVisualizationSupported: true,
+ },
+ },
+ } as any,
};
const assessmentData = new AssessmentDataBuilder()
@@ -978,7 +1211,12 @@ describe('AssessmentStoreTest', () => {
assessmentMock.setup(am => am.getVisualizationConfiguration()).returns(() => configStub);
const expectedInstancesMap = cloneDeep(generatedAssessmentInstancesMap);
- expectedInstancesMap.selector2.testStepResults[
+
+ // Selector 1 shouldn't change because it's already enabled
+ // Selector 2 shouldn't change because it doesn't support visualizations
+ // Selector 3 shouldn't change because it has no test step results
+ // Selector 4 should toggle from disabled to enabled:
+ expectedInstancesMap.selector4.testStepResults[
requirementKey
].isVisualizationEnabled = true;
diff --git a/src/tests/unit/tests/scanner/custom-rules/landmark-role.test.ts b/src/tests/unit/tests/scanner/custom-rules/landmark-role.test.ts
deleted file mode 100644
index 12e0a14e3a7..00000000000
--- a/src/tests/unit/tests/scanner/custom-rules/landmark-role.test.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { landmarkConfiguration } from '../../../../../scanner/custom-rules/landmark-rule';
-
-describe('landmarkRule', () => {
- describe('verify landmark configs', () => {
- it('should have correct props', () => {
- expect(landmarkConfiguration.rule.id).toBe('main-landmark');
- expect(landmarkConfiguration.rule.selector).toBe('[role=main], main');
- expect(landmarkConfiguration.rule.any[0]).toBe('unique-landmark');
- expect(landmarkConfiguration.checks.length).toBe(0);
- });
- });
-});