CSR-762 Update some tests, get GA working for inputs for keyboard navigation
This commit is contained in:
parent
d4100f4d26
commit
fff1aa1848
10 changed files with 205 additions and 371 deletions
|
|
@ -12,6 +12,8 @@
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
:value="value"
|
:value="value"
|
||||||
:checked="isChecked"
|
:checked="isChecked"
|
||||||
|
@blur="handleBlur"
|
||||||
|
@focus="handleFocus"
|
||||||
@keypress.enter="handleEventAction('keypressSubmit', $event)"
|
@keypress.enter="handleEventAction('keypressSubmit', $event)"
|
||||||
@change="handleEventAction('change', $event)" />
|
@change="handleEventAction('change', $event)" />
|
||||||
|
|
||||||
|
|
@ -56,6 +58,7 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
isRequired: Boolean,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -89,7 +92,10 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case eventTypes.CLICK:
|
case eventTypes.CLICK:
|
||||||
|
console.log("RADIO CLICK");
|
||||||
|
// falls through. Keep this comment for the linter
|
||||||
case eventTypes.KEYPRESS_SUBMIT:
|
case eventTypes.KEYPRESS_SUBMIT:
|
||||||
|
console.log("RADIO KEYPRESS CLICK");
|
||||||
this.handleClick(e);
|
this.handleClick(e);
|
||||||
break;
|
break;
|
||||||
case eventTypes.CHANGE:
|
case eventTypes.CHANGE:
|
||||||
|
|
@ -117,22 +123,61 @@ export default {
|
||||||
this.valueToEmit = this.value;
|
this.valueToEmit = this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.currentlySelectedValues =
|
||||||
|
window.currentlySelectedValues ?? {};
|
||||||
|
window.currentlySelectedValues[this.groupName] = this.value;
|
||||||
this.handleChange(this.valueToEmit);
|
this.handleChange(this.valueToEmit);
|
||||||
this.pushClickEventToGA();
|
|
||||||
},
|
},
|
||||||
handleClick(e) {
|
handleClick(e) {
|
||||||
this.handleSelectionChange(e);
|
this.handleSelectionChange(e);
|
||||||
|
// console.log("clicked/selected: ", this.valueToEmit)
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
this.pushClickEventToGA();
|
||||||
|
}
|
||||||
this.$emit("buttonClicked", this.valueToEmit);
|
this.$emit("buttonClicked", this.valueToEmit);
|
||||||
},
|
},
|
||||||
pushClickEventToGA() {
|
pushClickEventToGA(value) {
|
||||||
|
console.log("PUSHING: ", {
|
||||||
|
route: this.$route.query[queryStrings.FMG_PAGE],
|
||||||
|
value: value ?? this.value?.toString(),
|
||||||
|
valueToLogType: this.valueToLogType,
|
||||||
|
});
|
||||||
|
|
||||||
|
window.firedGaClickEventValues = window.firedGaClickEventValues ?? {}
|
||||||
|
window.firedGaClickEventValues[window.lastFocusedInputGroup] = value ?? this.value
|
||||||
this.pushEventToGA(
|
this.pushEventToGA(
|
||||||
this.$route.query[queryStrings.FMG_PAGE],
|
this.$route.query[queryStrings.FMG_PAGE],
|
||||||
this.GaActions.CLICKED,
|
this.GaActions.CLICKED,
|
||||||
this.value?.toString(),
|
value?.toString ?? this.value?.toString(),
|
||||||
true,
|
true,
|
||||||
this.valueToLogType
|
this.valueToLogType
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
handleBlur() {
|
||||||
|
window.lastFocusedInputGroup = this.groupName;
|
||||||
|
window.wasLastFocusedInputMultiselect = this.isMultiSelect
|
||||||
|
},
|
||||||
|
handleFocus() {
|
||||||
|
console.log("FOCUS: ", {
|
||||||
|
currentlySelectedValues: window.currentlySelectedValues,
|
||||||
|
firedGaClickEventValues: window.firedGaClickEventValues,
|
||||||
|
lastFocusedInputGroup: window.lastFocusedInputGroup,
|
||||||
|
wasLastFocusedInputMultiselect: window.wasLastFocusedInputMultiselect,
|
||||||
|
groupName: this.groupName
|
||||||
|
})
|
||||||
|
if (
|
||||||
|
window.currentlySelectedValues &&
|
||||||
|
window.firedGaClickEventValues &&
|
||||||
|
window.lastFocusedInputGroup &&
|
||||||
|
!window.wasLastFocusedInputMultiselect &&
|
||||||
|
window.currentlySelectedValues[window.lastFocusedInputGroup] &&
|
||||||
|
window.lastFocusedInputGroup != this.groupName &&
|
||||||
|
window.firedGaClickEventValues[window.lastFocusedInputGroup] != window.currentlySelectedValues[window.lastFocusedInputGroup]
|
||||||
|
) {
|
||||||
|
// TODO MAKE SURE THIS IS FIRING THE RIGHT VALUE
|
||||||
|
this.pushClickEventToGA(window.currentlySelectedValues[window.lastFocusedInputGroup])
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isChecked() {
|
isChecked() {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@
|
||||||
<legend
|
<legend
|
||||||
class="sr-only"
|
class="sr-only"
|
||||||
:data-focus-target="formatString(groupName)"
|
:data-focus-target="formatString(groupName)"
|
||||||
:id="formatString(groupName)"
|
:id="formatString(groupName)">
|
||||||
tabindex="-1">
|
|
||||||
{{ questionText }}
|
{{ questionText }}
|
||||||
{{
|
{{
|
||||||
isMultiSelect && answers && answers.length > 1
|
isMultiSelect && answers && answers.length > 1
|
||||||
|
|
@ -51,6 +50,8 @@
|
||||||
:validationRules="validationRules"
|
:validationRules="validationRules"
|
||||||
:textPosition="textPosition"
|
:textPosition="textPosition"
|
||||||
:selectOnKeypress="selectOnKeypress"
|
:selectOnKeypress="selectOnKeypress"
|
||||||
|
@blur="handleBlur"
|
||||||
|
@focus="handleFocus"
|
||||||
@buttonClicked="handleAnswerChange" />
|
@buttonClicked="handleAnswerChange" />
|
||||||
<!-- For nested questions -->
|
<!-- For nested questions -->
|
||||||
<transition name="fade" mode="out-in">
|
<transition name="fade" mode="out-in">
|
||||||
|
|
@ -123,6 +124,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
primaryValue: "",
|
primaryValue: "",
|
||||||
|
lastFocusedInputGroup: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -175,10 +177,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
buttonsInfo() {
|
buttonsInfo() {
|
||||||
console.log({
|
|
||||||
answers: this.answers,
|
|
||||||
isArray: Array.isArray(this.answers),
|
|
||||||
});
|
|
||||||
// TODO KO temporary. It should always just be an array
|
// TODO KO temporary. It should always just be an array
|
||||||
return (Array.isArray(this.answers) ? this.answers : [])?.map(
|
return (Array.isArray(this.answers) ? this.answers : [])?.map(
|
||||||
(answer) => ({
|
(answer) => ({
|
||||||
|
|
@ -191,7 +189,8 @@ export default {
|
||||||
buttonImageId: answer.buttonImageId ?? answer.ImageId,
|
buttonImageId: answer.buttonImageId ?? answer.ImageId,
|
||||||
groupName: this.formatString(this.groupName),
|
groupName: this.formatString(this.groupName),
|
||||||
value:
|
value:
|
||||||
answer.value ?? (this.useTextForValue
|
answer.value ??
|
||||||
|
(this.useTextForValue
|
||||||
? answer.Text
|
? answer.Text
|
||||||
: answer.Name ?? answer),
|
: answer.Name ?? answer),
|
||||||
})
|
})
|
||||||
|
|
@ -225,6 +224,17 @@ export default {
|
||||||
this.$emit("buttonQuestionChange", primaryAnswerValue);
|
this.$emit("buttonQuestionChange", primaryAnswerValue);
|
||||||
this.$emit("update:modelValue", primaryAnswerValue);
|
this.$emit("update:modelValue", primaryAnswerValue);
|
||||||
},
|
},
|
||||||
|
handleBlur() {
|
||||||
|
// this.lastFocusedInputGroup = this.groupName;
|
||||||
|
// window.lastFocusedInputGroup = this.groupName
|
||||||
|
// console.log("blur: ", this.groupName);
|
||||||
|
},
|
||||||
|
handleFocus() {
|
||||||
|
// console.log("focused: ", {
|
||||||
|
// groupName: this.groupName,
|
||||||
|
// lastFocusedInputGroup: this.lastFocusedInputGroup,
|
||||||
|
// });
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
listButton,
|
listButton,
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,73 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import windshieldChipCountQuestion from "@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question";
|
import windshieldChipCountQuestion from "@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import { nextTick } from "vue";
|
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
jest.mock("@/store", () => { return {}; }, {virtual: true});
|
jest.mock(
|
||||||
|
"@/store",
|
||||||
|
() => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
{ virtual: true }
|
||||||
|
);
|
||||||
|
|
||||||
describe("windshield-chip-count-question.vue", () => {
|
describe("windshield-chip-count-question.vue", () => {
|
||||||
test("Selected chip count is emitted upon selection.", async () => {
|
test("Selected chip count is emitted upon selection.", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({modelValueProp: ["One"]});
|
const { wrapper } = setupMocks({ modelValueProp: 1 });
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
wrapper.setValue({ modelValue: ["Two"] });
|
await wrapper.setData({ numberOfChips: 2 });
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
//Assert
|
||||||
//Assert
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([2]);
|
||||||
expect(wrapper.vm.selectedChipCountValues).toEqual(["One"]);
|
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: ["Two"] }]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Windshield-chip-count-question.vue", () => {
|
function setupMocks({
|
||||||
test("Should display question and answers from api.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({modelValueProp: ["One"]});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
wrapper.setProps({isAvailable: true});
|
|
||||||
wrapper.vm.updateSelectedValues = jest.fn();
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(wrapper.vm.updateSelectedValues).toBeCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
modelValueProp = ["Two"],
|
modelValueProp = ["Two"],
|
||||||
groupName = "WindshieldChipCountQuestion",
|
groupName = "WindshieldChipCountQuestion",
|
||||||
cmsQuestionText = "How many chips are we repairing?",
|
cmsQuestionText = "How many chips are we repairing?",
|
||||||
cmsAnswers = [{Name: "One"}, {Name: "Two"}, {Name: "Three"}],
|
cmsAnswers = [{ Name: "One" }, { Name: "Two" }, { Name: "Three" }],
|
||||||
dataFromStoreApi = [],
|
dataFromStoreApi = [],
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
//Mock store
|
//Mock store
|
||||||
store.dispatch = jest.fn(() => dataFromStoreApi);
|
store.dispatch = jest.fn(() => dataFromStoreApi);
|
||||||
store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
|
store.getters = {
|
||||||
|
vehicle: {
|
||||||
|
year: 2019,
|
||||||
|
make: "honda",
|
||||||
|
model: "civc",
|
||||||
|
style: "2 Door",
|
||||||
|
category: "CAR",
|
||||||
|
},
|
||||||
|
};
|
||||||
const mountOptions = getMountOptions({
|
const mountOptions = getMountOptions({
|
||||||
store: {
|
store: {
|
||||||
dispatch: store.dispatch,
|
dispatch: store.dispatch,
|
||||||
getters: store.getters,
|
getters: store.getters,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Mock props
|
//Mock props
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
getCmsContent: jest.fn()
|
getCmsContent: jest.fn(),
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
mountOptions.propsData = {
|
mountOptions.propsData = {
|
||||||
modelValue: modelValueProp
|
modelValue: modelValueProp,
|
||||||
};
|
};
|
||||||
mountOptions.mixins = [mockMixin];
|
mountOptions.mixins = [mockMixin];
|
||||||
|
|
||||||
const wrapper = shallowMount(windshieldChipCountQuestion, mountOptions);
|
const wrapper = shallowMount(windshieldChipCountQuestion, mountOptions);
|
||||||
|
|
||||||
//Mock CMS content
|
//Mock CMS content
|
||||||
const cmsContent = {
|
const cmsContent = {
|
||||||
groupName: groupName,
|
groupName: groupName,
|
||||||
QuestionText: cmsQuestionText,
|
QuestionText: cmsQuestionText,
|
||||||
Answers: cmsAnswers,
|
Answers: cmsAnswers,
|
||||||
};
|
};
|
||||||
const damageOptions = dataFromStoreApi;
|
const damageOptions = dataFromStoreApi;
|
||||||
return { wrapper, cmsContent, damageOptions };
|
return { wrapper, cmsContent, damageOptions };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,22 @@ import store from "@/store";
|
||||||
jest.mock("@/store", () => { return {}; }, {virtual: true});
|
jest.mock("@/store", () => { return {}; }, {virtual: true});
|
||||||
|
|
||||||
describe("windshield-damage-type-question.vue", () => {
|
describe("windshield-damage-type-question.vue", () => {
|
||||||
test("Selected chip count is emitted upon selection.", async () => {
|
test("Selected windshield damage is emitted upon selection.", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({modelValueProp: ["Repair"]});
|
const { wrapper } = setupMocks({modelValueProp: "Repair"});
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
wrapper.setValue({ modelValue: ["Replace"] });
|
wrapper.setValue({ modelValue: "Replace" });
|
||||||
await wrapper.vm.$nextTick();
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.selectedValues).toEqual(["Repair"]);
|
expect(wrapper.vm.selectedWindshieldDamageType).toEqual("Repair");
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: ["Replace"] }]);
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: "Replace" }]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
modelValueProp = ["Two"],
|
modelValueProp = "",
|
||||||
groupName = "WindshieldDamageTypeQuestion",
|
groupName = "WindshieldDamageTypeQuestion",
|
||||||
cmsQuestionText = "What's your windshield damage?",
|
cmsQuestionText = "What's your windshield damage?",
|
||||||
cmsAnswers = [{Name: "Repair"}, {Name: "Replace"}],
|
cmsAnswers = [{Name: "Repair"}, {Name: "Replace"}],
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,16 @@ export default {
|
||||||
buttonLabel: [Number, String],
|
buttonLabel: [Number, String],
|
||||||
buttonLabelSubCopy: String,
|
buttonLabelSubCopy: String,
|
||||||
buttonImage: String,
|
buttonImage: String,
|
||||||
altText: String,
|
altText: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
textPosition: String,
|
textPosition: String,
|
||||||
screenReaderOnlyText: String,
|
screenReaderOnlyText: String,
|
||||||
valueToLogType: String,
|
valueToLogType: String,
|
||||||
validationRules: String,
|
validationRules: String,
|
||||||
isWide: Boolean
|
isWide: Boolean,
|
||||||
|
isRequired: Boolean
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
buttonWrapperClasses="list-group list-button rounded-3 d-flex flex-column w-100 mb-2"
|
buttonWrapperClasses="list-group list-button rounded-3 d-flex flex-column w-100 mb-2"
|
||||||
@buttonClicked="handleAnswerChange">
|
@buttonClicked="handleAnswerChange">
|
||||||
<div
|
<div
|
||||||
tabindex="-1"
|
|
||||||
:aria-label="buttonLabel"
|
:aria-label="buttonLabel"
|
||||||
class="list-button-content d-flex flex-column justify-content-center py-3 px-4">
|
class="list-button-content d-flex flex-column justify-content-center py-3 px-4">
|
||||||
<span class="m-0" :class="textPosition">
|
<span class="m-0" :class="textPosition">
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { mount } from "@vue/test-utils";
|
||||||
import listCard from "./list-card";
|
import listCard from "./list-card";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
import { GaActions } from "@/constants/analytics";
|
import { GaActions } from "@/constants/analytics";
|
||||||
|
|
||||||
describe("list-card.vue", () => {
|
describe("list-card.vue", () => {
|
||||||
it("Should return input type checkbox if isMultiSelect is true", async () => {
|
it("Should return input type checkbox if isMultiSelect is true", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isMultiSelect: true,
|
isMultiSelect: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -22,9 +22,9 @@ describe("list-card.vue", () => {
|
||||||
expect(input.attributes().type).toEqual("checkbox");
|
expect(input.attributes().type).toEqual("checkbox");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return primary label text", async () => {
|
it("Should return primary label text", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -40,9 +40,9 @@ describe("list-card.vue", () => {
|
||||||
expect(paragraph.text()).toEqual("Windshield");
|
expect(paragraph.text()).toEqual("Windshield");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return secondary (sub) label text", async () => {
|
it("Should return secondary (sub) label text", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -59,28 +59,9 @@ describe("list-card.vue", () => {
|
||||||
expect(paragraph.text()).toEqual("Test");
|
expect(paragraph.text()).toEqual("Test");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return value used for various text settings including the label 'for' and input id", async () => {
|
it("Should return input group name used for radio or checkbox", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
|
||||||
isRadioHorizontal: true,
|
|
||||||
buttonLabel: "Windshield",
|
|
||||||
buttonID: "List Card Checkbox",
|
|
||||||
groupID: "radio-demo-1",
|
|
||||||
groupName: "radio 1",
|
|
||||||
buttonImage: "windshield-damage.svg",
|
|
||||||
buttonLabelSubCopy: "Test",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const label = wrapper.find("label");
|
|
||||||
expect(label.attributes().for).toEqual("List Card Checkbox");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should return input group name used for radio or checkbox", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -97,9 +78,9 @@ describe("list-card.vue", () => {
|
||||||
expect(input.attributes().name).toEqual("radio 1");
|
expect(input.attributes().name).toEqual("radio 1");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return aria-required state", async () => {
|
it("Should return aria-required state", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -116,9 +97,9 @@ describe("list-card.vue", () => {
|
||||||
expect(input.attributes()["aria-required"]).toEqual("true");
|
expect(input.attributes()["aria-required"]).toEqual("true");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return flex row classes if isWide is true", async () => {
|
it("Should return flex row classes if isWide is true", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -133,13 +114,16 @@ describe("list-card.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find(".list-card-content");
|
||||||
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-2", "ps-4", "pe-4"]);
|
expect(label.exists()).toBe(true);
|
||||||
|
const labelClasses = wrapper.vm.labelClasses;
|
||||||
|
expect(labelClasses).toContain("flex-row");
|
||||||
|
expect(label.classes()).toContain("flex-row");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is true", async () => {
|
it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is provided", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -154,13 +138,18 @@ describe("list-card.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find(".list-card-content");
|
||||||
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-2", "ps-4", "pe-4", "checkboxTop"]);
|
expect(label.exists()).toBe(true);
|
||||||
|
const labelClasses = wrapper.vm.labelClasses;
|
||||||
|
expect(labelClasses).toContain("flex-row");
|
||||||
|
expect(label.classes()).toContain("flex-row");
|
||||||
|
expect(labelClasses).toContain("checkboxTop");
|
||||||
|
expect(label.classes()).toContain("checkboxTop");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return flex column classes if isWide is false", async () => {
|
it("Should return flex column classes if isWide is false", () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(listCard, {
|
const wrapper = mount(listCard, {
|
||||||
propsData: {
|
propsData: {
|
||||||
isRadioHorizontal: true,
|
isRadioHorizontal: true,
|
||||||
buttonLabel: "Windshield",
|
buttonLabel: "Windshield",
|
||||||
|
|
@ -174,161 +163,10 @@ describe("list-card.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find(".list-card-content");
|
||||||
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-column", "pt-4", "pb-3"]);
|
expect(label.exists()).toBe(true);
|
||||||
|
const labelClasses = wrapper.vm.labelClasses;
|
||||||
|
expect(labelClasses).toContain("flex-column");
|
||||||
|
expect(label.classes()).toContain("flex-column");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should emit button value on click", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
|
||||||
isRadioHorizontal: true,
|
|
||||||
buttonLabel: "Windshield",
|
|
||||||
value: "List Card Checkbox",
|
|
||||||
groupID: "radio-demo-1",
|
|
||||||
groupName: "radio 1",
|
|
||||||
buttonImage: "windshield-damage.svg",
|
|
||||||
isRequired: true,
|
|
||||||
isWide: false,
|
|
||||||
buttonID: 'list-card-id',
|
|
||||||
selectedValues: "List Card Checkbox"
|
|
||||||
},
|
|
||||||
});
|
|
||||||
wrapper.vm.handleCheckChange();
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: true, buttonId: 'list-card-id'}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
|
||||||
isRadioHorizontal: true,
|
|
||||||
buttonLabel: "Windshield",
|
|
||||||
value: "List Card Checkbox",
|
|
||||||
groupID: "radio-demo-1",
|
|
||||||
groupName: "radio 1",
|
|
||||||
buttonImage: "windshield-damage.svg",
|
|
||||||
isRequired: true,
|
|
||||||
isWide: false,
|
|
||||||
selectedValues: "Car-Front"
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.componentVM.checkValue).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should set an initial value for validation if selectedValues include the value", async () => {
|
|
||||||
// Arrange
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
|
||||||
value: "Windshield",
|
|
||||||
groupName: "radio 1",
|
|
||||||
selectedValues: ["Windshield"],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.fieldOptions.initialValue).toEqual([ 'Windshield' ]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
|
||||||
selectingInitiatesLoad: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
wrapper.vm.handleInputChange();
|
|
||||||
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
|
||||||
isMultiSelect: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
wrapper.vm.handleKeyupArrow();
|
|
||||||
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
propsData: {
|
|
||||||
selectingInitiatesLoad: false,
|
|
||||||
isMultiSelect: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
wrapper.vm.handleKeyupArrow();
|
|
||||||
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should run handleChange if triggerButton is triggered", async () => {
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
global: {
|
|
||||||
mocks: {
|
|
||||||
'$route': { query: { fmgPage: 'page-name' } },
|
|
||||||
GaActions: GaActions,
|
|
||||||
pushEventToGA: jest.fn(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
selectingInitiatesLoad: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
wrapper.vm.triggerButton();
|
|
||||||
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
expect(wrapper.vm.handleChange).toBeCalled;
|
|
||||||
expect(wrapper.vm.handleCheckChange).not.toBeCalled;
|
|
||||||
expect(wrapper.vm.displayLoader).not.toBeCalled;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should run handleCheckChange and displayLoader if triggerButton is triggered and seletingInitiatesLoad is true", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(listCard, {
|
|
||||||
global: {
|
|
||||||
mocks: {
|
|
||||||
'$route': { query: { fmgPage: 'page-name' } },
|
|
||||||
GaActions: GaActions,
|
|
||||||
pushEventToGA: jest.fn(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
selectingInitiatesLoad: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
wrapper.vm.triggerButton();
|
|
||||||
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
|
||||||
expect(wrapper.vm.displayLoader).toBeCalled;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
@buttonClicked="handleAnswerChange">
|
@buttonClicked="handleAnswerChange">
|
||||||
<div
|
<div
|
||||||
class="d-flex w-100 align-items-center px-2 h-100 list-card-content"
|
class="d-flex w-100 align-items-center px-2 h-100 list-card-content"
|
||||||
:class="getLabelClasses">
|
:class="labelClasses">
|
||||||
<img
|
<img
|
||||||
:id="buttonImageId"
|
:id="buttonImageId"
|
||||||
:class="!isWide ? 'order-1' : 'ms-auto order-3'"
|
:class="!isWide ? 'order-1' : 'ms-auto order-3'"
|
||||||
|
|
@ -46,7 +46,7 @@ export default {
|
||||||
baseInputButton,
|
baseInputButton,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
getLabelClasses() {
|
labelClasses() {
|
||||||
if (this.isWide) {
|
if (this.isWide) {
|
||||||
let classes = "flex-row py-2 ps-4 pe-4";
|
let classes = "flex-row py-2 ps-4 pe-4";
|
||||||
if (this.buttonLabelSubCopy) {
|
if (this.buttonLabelSubCopy) {
|
||||||
|
|
|
||||||
|
|
@ -1,117 +1,60 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { mount } from "@vue/test-utils";
|
||||||
import radio from "./radio";
|
import radio from "./radio";
|
||||||
import { nextTick } from "vue";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import { GaActions } from "@/constants/analytics";
|
import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
|
||||||
|
|
||||||
describe("radio.vue", () => {
|
describe("radio.vue", () => {
|
||||||
it("Should return group name", async () => {
|
it("Should have correct group name", async () => {
|
||||||
// Act
|
// Arrange
|
||||||
const wrapper = shallowMount(radio, {
|
let { wrapper } = setupMocks({});
|
||||||
propsData: {
|
|
||||||
groupName: "radio-button-test",
|
// Act
|
||||||
},
|
await wrapper.setProps({
|
||||||
|
groupName: "radio-button-test",
|
||||||
|
});
|
||||||
|
const input = wrapper.find("input");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(input.attributes().name).toEqual("radio-button-test");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
it("Should have correct label text", async () => {
|
||||||
const input = wrapper.find("input");
|
// Act
|
||||||
|
let { wrapper } = setupMocks({});
|
||||||
|
|
||||||
// Expect
|
// Arrange
|
||||||
expect(input.attributes().name).toEqual("radio-button-test");
|
await wrapper.setProps({
|
||||||
});
|
buttonLabel: "label text",
|
||||||
|
});
|
||||||
|
const paragraph = wrapper.find("p");
|
||||||
|
|
||||||
it("Should return checkbox id", async () => {
|
// Assert
|
||||||
// Act
|
expect(paragraph.text()).toEqual("label text");
|
||||||
const wrapper = shallowMount(radio, {
|
|
||||||
propsData: {
|
|
||||||
buttonID: "Radio ID",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
it("Should have correct screenreader-only text", async () => {
|
||||||
const input = wrapper.find("input");
|
// Act
|
||||||
|
let { wrapper } = setupMocks({});
|
||||||
|
|
||||||
// Expect
|
// Arrange
|
||||||
expect(input.attributes().id).toEqual("Radio ID");
|
await wrapper.setProps({
|
||||||
});
|
screenReaderOnlyText: "screenreader text",
|
||||||
|
});
|
||||||
|
const paragraph = wrapper.find(".sr-only");
|
||||||
|
|
||||||
it("Should return label text", async () => {
|
// Assert
|
||||||
// Act
|
expect(paragraph.text()).toEqual("screenreader text");
|
||||||
const wrapper = shallowMount(radio, {
|
|
||||||
propsData: {
|
|
||||||
buttonLabel: "label text",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
|
||||||
const paragraph = wrapper.find("p");
|
|
||||||
|
|
||||||
expect(paragraph.text()).toEqual("label text");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should return label text", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(radio, {
|
|
||||||
propsData: {
|
|
||||||
screenReaderOnlyText: "screenreader text",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const paragraph = wrapper.find("span");
|
|
||||||
|
|
||||||
expect(paragraph.text()).toEqual("screenreader text");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should emit button value on click", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(radio, {
|
|
||||||
global: {
|
|
||||||
mocks: {
|
|
||||||
'$route': { query: { fmgPage: 'page-name' } },
|
|
||||||
GaActions: GaActions,
|
|
||||||
pushEventToGA: jest.fn(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
buttonLabel: "Windshield",
|
|
||||||
value: "List Card Checkbox",
|
|
||||||
buttonID: "List Card Checkbox",
|
|
||||||
groupID: "radio-demo-1",
|
|
||||||
groupName: "radio 1",
|
|
||||||
isRequired: true,
|
|
||||||
isWide: false,
|
|
||||||
modelValue: ["List Card Checkbox"],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
wrapper.vm.handleCheckChange();
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{"buttonID": "List Card Checkbox", value: "List Card Checkbox", checkValue: false}]);;
|
|
||||||
expect(wrapper.vm.pushEventToGA).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
|
|
||||||
// Act
|
|
||||||
const wrapper = shallowMount(radio, {
|
|
||||||
global: {
|
|
||||||
mocks: {
|
|
||||||
'$route': { query: { fmgPage: 'page-name' } },
|
|
||||||
GaActions: GaActions,
|
|
||||||
pushEventToGA: jest.fn(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
propsData: {
|
|
||||||
buttonLabel: "Windshield",
|
|
||||||
buttonID: "List Card Checkbox",
|
|
||||||
groupID: "radio-demo-1",
|
|
||||||
groupName: "radio 1",
|
|
||||||
buttonImage: "windshield-damage.svg",
|
|
||||||
isRequired: true,
|
|
||||||
modelValue: ["List Card Checkbox"],
|
|
||||||
value: "Car-Front",
|
|
||||||
selectedValues: "Car-Front"
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.componentVM.checkValue).toEqual(true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setupMocks({ mountOptionsMockData = {} }) {
|
||||||
|
const wrapper = mount(
|
||||||
|
radio,
|
||||||
|
getMountOptions({
|
||||||
|
...mountOptionsMockData,
|
||||||
|
mixins: [inputButtonWrapperMixin],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
buttonWrapperClasses="ui-radio form-check"
|
buttonWrapperClasses="ui-radio form-check"
|
||||||
inputClasses="form-check-input"
|
inputClasses="form-check-input"
|
||||||
@buttonClicked="handleAnswerChange">
|
@buttonClicked="handleAnswerChange">
|
||||||
<div class="d-flex align-items-start form-check-label" :for="buttonID">
|
<div class="d-flex align-items-start form-check-label">
|
||||||
<p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p>
|
<p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p>
|
||||||
<span v-if="screenReaderOnlyText" class="sr-only">{{
|
<span v-if="screenReaderOnlyText" class="sr-only">{{
|
||||||
screenReaderOnlyText
|
screenReaderOnlyText
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue