Skip to content

Commit

Permalink
Merge pull request #712 from madeindjs/WF-125
Browse files Browse the repository at this point in the history
test(ui): introduce functional tests - WF-125
  • Loading branch information
ramedina86 authored Jan 7, 2025
2 parents db2b440 + b468c1f commit 262a521
Show file tree
Hide file tree
Showing 14 changed files with 1,328 additions and 3 deletions.
572 changes: 569 additions & 3 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@
"@typescript-eslint/eslint-plugin": "7.18.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/test-utils": "^2.4.6",
"eslint": "^8.39.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-storybook": "0.8.0",
"eslint-plugin-vue": "^9.28.0",
"postcss": "^8.4.49",
"postcss-assign-layer": "^0.4.0",
"jsdom": "^25.0.1",
"prettier": "3.2.5",
"storybook": "8.0.5",
"vite": "^5.2.7",
Expand Down
48 changes: 48 additions & 0 deletions src/ui/src/builder/settings/BuilderSettingsProperties.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { describe, expect, it } from "vitest";
import BuilderSettingsProperties from "./BuilderSettingsProperties.vue";
import { shallowMount } from "@vue/test-utils";
import {
buildMockComponent,
buildMockCore,
mockInstancePath,
mockProvides,
} from "@/tests/mocks";
import injectionKeys from "@/injectionKeys";
import { generateBuilderManager } from "../builderManager";
import { flattenInstancePath } from "@/renderer/instancePath";
import WdsFieldWrapper from "@/wds/WdsFieldWrapper.vue";
import templateMap from "@/core/templateMap";

describe("BuilderSettingsProperties", () => {
it.each(Object.keys(templateMap))(
"should render settings for %s",
(type) => {
const { core } = buildMockCore();
const component = buildMockComponent({ type });
core.addComponent(component);

const ssbm = generateBuilderManager();
ssbm.setSelection(
component.id,
flattenInstancePath(mockInstancePath),
"click",
);

const wrapper = shallowMount(BuilderSettingsProperties, {
global: {
provide: {
...mockProvides,
[injectionKeys.builderManager as symbol]: ssbm,
[injectionKeys.core as symbol]: core,
},
},
});

// check that each fields is renderer
expect(wrapper.findAllComponents(WdsFieldWrapper)).toHaveLength(
// @ts-expect-error TS doesn't infer the right type for the component
Object.keys(templateMap[type].writer.fields).length,
);
},
);
});
58 changes: 58 additions & 0 deletions src/ui/src/components/core/input/CoreCheckboxInput.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { describe, expect, it, vi } from "vitest";

import CoreCheckboxInput from "./CoreCheckboxInput.vue";
import { flushPromises, mount } from "@vue/test-utils";
import injectionKeys from "@/injectionKeys";
import { ref } from "vue";
import { buildMockComponent, buildMockCore, mockProvides } from "@/tests/mocks";

describe("CoreCheckboxInput", () => {
it("should render value from the state and forward emit", async () => {
const { core, userState } = buildMockCore();
userState.value = { key: ["b"] };

core.addComponent(
buildMockComponent({
handlers: { "wf-options-change": "python_handler" },
binding: {
eventType: "",
stateRef: "key",
},
}),
);

const wrapper = mount(CoreCheckboxInput, {
global: {
provide: {
...mockProvides,
[injectionKeys.core as symbol]: core,
[injectionKeys.evaluatedFields as symbol]: {
label: ref("This is the label"),
orientation: ref("horizontal"),
options: ref({ a: "Option A", b: "Option B" }),
},
},
},
});

await flushPromises();

const options = wrapper.findAll("input");
expect(options).toHaveLength(2);

const optionA = options.at(0);
expect(optionA.attributes().value).toBe("a");
expect(optionA.element.checked).toBe(false);

const optionB = options.at(1);
expect(optionB.attributes().value).toBe("b");
expect(optionB.element.checked).toBe(true);

const dispatchEvent = vi.spyOn(wrapper.vm.$el, "dispatchEvent");
await optionA.trigger("input");
await flushPromises();
expect(dispatchEvent).toHaveBeenCalledOnce();

expect(wrapper.element).toMatchSnapshot();
});
});
50 changes: 50 additions & 0 deletions src/ui/src/components/core/input/CoreDateInput.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { describe, expect, it, vi } from "vitest";

import CoreDateInput from "./CoreDateInput.vue";
import { flushPromises, mount } from "@vue/test-utils";
import injectionKeys from "@/injectionKeys";
import { ref } from "vue";
import { buildMockComponent, buildMockCore, mockProvides } from "@/tests/mocks";

describe("CoreDateInput", () => {
it("should render value from the state and forward emit", async () => {
const { core, userState } = buildMockCore();
userState.value = { key: "2024-12-14" };
core.addComponent(
buildMockComponent({
handlers: { "wf-date-change": "python_handler" },
binding: {
eventType: "",
stateRef: "key",
},
}),
);

const wrapper = mount(CoreDateInput, {
global: {
provide: {
...mockProvides,
[injectionKeys.core as symbol]: core,
[injectionKeys.evaluatedFields as symbol]: {
label: ref("This is the label"),
},
},
},
});

await flushPromises();

const input = wrapper.get("input");
expect(input.element.value).toStrictEqual("2024-12-14");

const dispatchEvent = vi.spyOn(wrapper.vm.$el, "dispatchEvent");

await input.trigger("change");

await flushPromises();

expect(dispatchEvent).toHaveBeenCalledOnce();

expect(wrapper.element).toMatchSnapshot();
});
});
58 changes: 58 additions & 0 deletions src/ui/src/components/core/input/CoreRadioInput.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { describe, expect, it, vi } from "vitest";

import CoreRadioInput from "./CoreRadioInput.vue";
import { flushPromises, mount } from "@vue/test-utils";
import injectionKeys from "@/injectionKeys";
import { ref } from "vue";
import { buildMockComponent, buildMockCore, mockProvides } from "@/tests/mocks";

describe("CoreRadioInput", () => {
it("should render value from the state and forward emit", async () => {
const { core, userState } = buildMockCore();
userState.value = { key: "b" };

core.addComponent(
buildMockComponent({
handlers: { "wf-option-change": "python_handler" },
binding: {
eventType: "",
stateRef: "key",
},
}),
);

const wrapper = mount(CoreRadioInput, {
global: {
provide: {
...mockProvides,
[injectionKeys.core as symbol]: core,
[injectionKeys.evaluatedFields as symbol]: {
label: ref("This is the label"),
orientation: ref("horizontal"),
options: ref({ a: "Option A", b: "Option B" }),
},
},
},
});

await flushPromises();

const options = wrapper.findAll("input");
expect(options).toHaveLength(2);

const optionA = options.at(0);
expect(optionA.attributes().value).toBe("a");
expect(optionA.element.checked).toBe(false);

const optionB = options.at(1);
expect(optionB.attributes().value).toBe("b");
expect(optionB.element.checked).toBe(true);

const dispatchEvent = vi.spyOn(wrapper.vm.$el, "dispatchEvent");
await optionA.trigger("input");
await flushPromises();
expect(dispatchEvent).toHaveBeenCalledOnce();

expect(wrapper.element).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`CoreCheckboxInput > should render value from the state and forward emit 1`] = `
<div
class="BaseInputWrapper CoreCheckboxInput"
data-v-7a72f1be=""
data-v-7e12caaf=""
>
<label
data-v-7e12caaf=""
>
This is the label
</label>
<div
class="options horizontal"
data-v-7a72f1be=""
>
<div
class="option"
data-v-7a72f1be=""
>
<input
data-v-7a72f1be=""
type="checkbox"
value="a"
/>
<label
data-v-7a72f1be=""
for="component-id-test:0-option-a"
>
Option A
</label>
</div>
<div
class="option"
data-v-7a72f1be=""
>
<input
data-v-7a72f1be=""
type="checkbox"
value="b"
/>
<label
data-v-7a72f1be=""
for="component-id-test:0-option-b"
>
Option B
</label>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`CoreDateInput > should render value from the state and forward emit 1`] = `
<div
class="BaseInputWrapper CoreDateInput"
data-v-7e12caaf=""
data-v-acf95c76=""
>
<label
data-v-7e12caaf=""
>
This is the label
</label>
<input
data-v-acf95c76=""
type="date"
/>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`CoreRadioInput > should render value from the state and forward emit 1`] = `
<div
class="BaseInputWrapper CoreRadioInput"
data-v-7e12caaf=""
data-v-d075b11d=""
>
<label
data-v-7e12caaf=""
>
This is the label
</label>
<div
class="options horizontal"
data-v-d075b11d=""
>
<div
class="option"
data-v-d075b11d=""
>
<input
data-v-d075b11d=""
id="component-id-test:0-option-a"
name="component-id-test:0-options"
type="radio"
value="a"
/>
<label
data-v-d075b11d=""
for="component-id-test:0-option-a"
>
Option A
</label>
</div>
<div
class="option"
data-v-d075b11d=""
>
<input
data-v-d075b11d=""
id="component-id-test:0-option-b"
name="component-id-test:0-options"
type="radio"
value="b"
/>
<label
data-v-d075b11d=""
for="component-id-test:0-option-b"
>
Option B
</label>
</div>
</div>
</div>
`;
Loading

0 comments on commit 262a521

Please sign in to comment.