mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-21 11:32:00 +02:00
19.0 vanilla
This commit is contained in:
parent
d1963a3c3a
commit
2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions
|
|
@ -0,0 +1,75 @@
|
|||
import { expect, test } from "@odoo/hoot";
|
||||
import { contains, defineModels, fields, models, mountView } from "@web/../tests/web_test_helpers";
|
||||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
|
||||
class Partner extends models.Model {
|
||||
lines = fields.One2many({ relation: "lines_sections" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
lines: [1, 2],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
class LinesSections extends models.Model {
|
||||
_name = "lines_sections";
|
||||
|
||||
is_page = fields.Boolean();
|
||||
title = fields.Char();
|
||||
random_questions_count = fields.Integer({ string: "Question Count" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
is_page: true,
|
||||
title: "firstSectionTitle",
|
||||
random_questions_count: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
is_page: false,
|
||||
title: "recordTitle",
|
||||
random_questions_count: 5,
|
||||
},
|
||||
];
|
||||
_views = {
|
||||
form: /* xml */ `
|
||||
<form>
|
||||
<field name="title" />
|
||||
</form>
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
defineModels([Partner, LinesSections]);
|
||||
defineMailModels();
|
||||
|
||||
test("button is visible in the edited record and allows to open that record", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
expect("td.o_survey_description_page_cell").toHaveCount(2);
|
||||
expect("button.o_icon_button").toHaveCount(0);
|
||||
|
||||
await contains(".o_data_cell").click();
|
||||
expect(".o_data_row button.o_icon_button").toHaveCount(1);
|
||||
expect(".modal .o_form_view").toHaveCount(0);
|
||||
|
||||
await contains("button.o_icon_button").click();
|
||||
expect(".modal .o_form_view").toHaveCount(1);
|
||||
});
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { click, getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
QUnit.module("DescriptionPageField", (hooks) => {
|
||||
let serverData;
|
||||
let target;
|
||||
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
fields: { lines: { type: "one2many", relation: "lines_sections" } },
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
lines: [1, 2],
|
||||
},
|
||||
],
|
||||
},
|
||||
lines_sections: {
|
||||
fields: {
|
||||
is_page: { type: "boolean" },
|
||||
title: { type: "char", string: "Title" },
|
||||
random_questions_count: { type: "number", string: "Question Count" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
is_page: true,
|
||||
title: "firstSectionTitle",
|
||||
random_questions_count: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
is_page: false,
|
||||
title: "recordTitle",
|
||||
random_questions_count: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
views: {
|
||||
"lines_sections,false,form": `
|
||||
<form>
|
||||
<field name="title" />
|
||||
</form>
|
||||
`,
|
||||
},
|
||||
};
|
||||
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"button is visible in the edited record and allows to open that record",
|
||||
async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="random_questions_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsN(target, "td.o_survey_description_page_cell", 2);
|
||||
assert.containsNone(target, "button.o_icon_button");
|
||||
|
||||
await click(target.querySelector(".o_data_cell"));
|
||||
assert.containsOnce(target.querySelector(".o_data_row"), "button.o_icon_button");
|
||||
assert.containsNone(target, ".modal .o_form_view");
|
||||
|
||||
await click(target, "button.o_icon_button");
|
||||
assert.containsOnce(target, ".modal .o_form_view");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
import { expect, test } from "@odoo/hoot";
|
||||
import { contains, defineModels, fields, models, mountView } from "@web/../tests/web_test_helpers";
|
||||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
|
||||
class Partner extends models.Model {
|
||||
lines = fields.One2many({ relation: "lines_sections" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
lines: [1, 2],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
class LinesSections extends models.Model {
|
||||
_name = "lines_sections";
|
||||
|
||||
is_page = fields.Boolean();
|
||||
title = fields.Char();
|
||||
random_questions_count = fields.Integer({ string: "Question Count" });
|
||||
sequence = fields.Integer();
|
||||
question_type = fields.Char();
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
sequence: 1,
|
||||
is_page: true,
|
||||
question_type: false,
|
||||
title: "firstSectionTitle",
|
||||
random_questions_count: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
sequence: 2,
|
||||
is_page: false,
|
||||
question_type: "simple_choice",
|
||||
title: "recordTitle",
|
||||
random_questions_count: 5,
|
||||
},
|
||||
];
|
||||
_views = {
|
||||
form: /* xml */ `
|
||||
<form>
|
||||
<field name="title" />
|
||||
</form>
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
defineModels([Partner, LinesSections]);
|
||||
defineMailModels();
|
||||
|
||||
const SELECTORS = {
|
||||
section: "tr.o_is_section > td.o_survey_description_page_cell",
|
||||
numberQuestions: "tr.o_is_section > [name='random_questions_count']",
|
||||
};
|
||||
|
||||
test("normal list view", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="question_type" />
|
||||
<field name="is_page" column_invisible="1"/>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
expect("td.o_survey_description_page_cell").toHaveCount(2); // Check if we have the two rows in the list
|
||||
|
||||
expect("tr.o_is_section").toHaveCount(1); // Check if we have only one section row
|
||||
expect(SELECTORS.section).toHaveProperty("colSpan", 2);
|
||||
|
||||
await contains(SELECTORS.section).click();
|
||||
expect(SELECTORS.section + " div.input-group").toHaveCount(1);
|
||||
});
|
||||
|
||||
test("list view with random count", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="question_type" />
|
||||
<field name="is_page" column_invisible="1"/>
|
||||
<field name="random_questions_count"/>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
expect("td.o_survey_description_page_cell").toHaveCount(2); // Check if we have the two rows in the list
|
||||
|
||||
expect("tr.o_is_section").toHaveCount(1); // Check if we have only one section row
|
||||
expect(SELECTORS.section).toHaveProperty("colSpan", 2);
|
||||
|
||||
// We can edit the section title
|
||||
await contains(SELECTORS.section).click();
|
||||
expect(SELECTORS.section + " div.input-group").toHaveCount(1);
|
||||
|
||||
// We can edit the number of random questions selected
|
||||
await contains(SELECTORS.numberQuestions).click();
|
||||
expect(SELECTORS.numberQuestions + " div").toHaveCount(1);
|
||||
});
|
||||
|
||||
test("list view with random but with question_type at the left of the title", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="question_type" />
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="is_page" column_invisible="1"/>
|
||||
<field name="random_questions_count"/>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
expect("td.o_survey_description_page_cell").toHaveCount(2); // Check if we have the two rows in the list
|
||||
|
||||
expect("tr.o_is_section").toHaveCount(1); // Check if we have only one section row
|
||||
expect(SELECTORS.section).toHaveProperty("colSpan", 1);
|
||||
|
||||
await contains(SELECTORS.section).click();
|
||||
expect(SELECTORS.section + " div.input-group").toHaveCount(1);
|
||||
|
||||
await contains(SELECTORS.numberQuestions).click();
|
||||
expect(SELECTORS.numberQuestions + " div").toHaveCount(1);
|
||||
});
|
||||
test("list view with random and question_type at the beginning of row", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="random_questions_count"/>
|
||||
<field name="question_type" />
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="is_page" column_invisible="1"/>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
expect("td.o_survey_description_page_cell").toHaveCount(2); // Check if we have the two rows in the list
|
||||
|
||||
expect("tr.o_is_section").toHaveCount(1); // Check if we have only one section row
|
||||
expect(SELECTORS.section).toHaveProperty("colSpan", 1);
|
||||
|
||||
await contains(SELECTORS.section).click();
|
||||
expect(SELECTORS.section + " div.input-group").toHaveCount(1);
|
||||
|
||||
await contains(SELECTORS.numberQuestions).click();
|
||||
expect(SELECTORS.numberQuestions + " div").toHaveCount(1);
|
||||
});
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { click, getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
QUnit.module("QuestionPageListRenderer", (hooks) => {
|
||||
let serverData;
|
||||
let target;
|
||||
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
fields: { lines: { type: "one2many", relation: "lines_sections" } },
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
lines: [1, 2],
|
||||
},
|
||||
],
|
||||
},
|
||||
lines_sections: {
|
||||
fields: {
|
||||
sequence: { type: "number" },
|
||||
is_page: { type: "boolean" },
|
||||
title: { type: "char", string: "Title" },
|
||||
question_type: { type: "string" },
|
||||
random_questions_count: { type: "number", string: "Question Count" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
sequence: 1,
|
||||
is_page: true,
|
||||
question_type: false,
|
||||
title: "firstSectionTitle",
|
||||
random_questions_count: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
sequence: 2,
|
||||
is_page: false,
|
||||
question_type: 'simple_choice',
|
||||
title: "recordTitle",
|
||||
random_questions_count: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
views: {
|
||||
"lines_sections,false,form": `
|
||||
<form>
|
||||
<field name="title" />
|
||||
</form>
|
||||
`,
|
||||
},
|
||||
};
|
||||
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"normal list view",
|
||||
async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="question_type" />
|
||||
<field name="is_page" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsN(target, "td.o_survey_description_page_cell", 2); // Check if we have the two rows in the list
|
||||
|
||||
assert.containsOnce(target, "tr.o_is_section"); // Check if we have only one section row
|
||||
const section = target.querySelector("tr.o_is_section > td.o_survey_description_page_cell");
|
||||
assert.strictEqual(section.colSpan, 2, 'The section should have a colspan of 1');
|
||||
|
||||
await click(section);
|
||||
assert.containsOnce(section, 'div.input-group');
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"list view with random count",
|
||||
async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="question_type" />
|
||||
<field name="is_page" invisible="1"/>
|
||||
<field name="random_questions_count"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsN(target, "td.o_survey_description_page_cell", 2); // Check if we have the two rows in the list
|
||||
|
||||
assert.containsOnce(target, "tr.o_is_section"); // Check if we have only one section row
|
||||
const section = target.querySelector("tr.o_is_section > td.o_survey_description_page_cell");
|
||||
assert.strictEqual(section.colSpan, 2, 'The section should have a colspan of 2');
|
||||
|
||||
// We can edit the section title
|
||||
await click(section);
|
||||
assert.containsOnce(section, 'div.input-group');
|
||||
|
||||
//We can edit the number of random questions selected
|
||||
const numberQuestions = target.querySelector("tr.o_is_section > [name='random_questions_count']");
|
||||
await click(numberQuestions);
|
||||
assert.containsOnce(numberQuestions, 'div');
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"list view with random but with question_type at the left of the title",
|
||||
async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="question_type" />
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="is_page" invisible="1"/>
|
||||
<field name="random_questions_count"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsN(target, "td.o_survey_description_page_cell", 2); // Check if we have the two rows in the list
|
||||
|
||||
assert.containsOnce(target, "tr.o_is_section"); // Check if we have only one section row
|
||||
const section = target.querySelector("tr.o_is_section > td.o_survey_description_page_cell");
|
||||
assert.strictEqual(section.colSpan, 1, 'The section should have a colspan of 1');
|
||||
|
||||
await click(section);
|
||||
assert.containsOnce(section, 'div.input-group');
|
||||
|
||||
const numberQuestions = target.querySelector("tr.o_is_section > [name='random_questions_count']");
|
||||
await click(numberQuestions);
|
||||
assert.containsOnce(numberQuestions, 'div');
|
||||
}
|
||||
);
|
||||
QUnit.test(
|
||||
"list view with random and question_type at the beginning of row",
|
||||
async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="random_questions_count"/>
|
||||
<field name="question_type" />
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="is_page" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsN(target, "td.o_survey_description_page_cell", 2); // Check if we have the two rows in the list
|
||||
|
||||
assert.containsOnce(target, "tr.o_is_section"); // Check if we have only one section row
|
||||
const section = target.querySelector("tr.o_is_section > td.o_survey_description_page_cell");
|
||||
assert.strictEqual(section.colSpan, 1, 'The section should have a colspan of 1');
|
||||
|
||||
await click(section);
|
||||
assert.containsOnce(section, 'div.input-group');
|
||||
|
||||
const numberQuestions = target.querySelector("tr.o_is_section > [name='random_questions_count']");
|
||||
await click(numberQuestions);
|
||||
assert.containsOnce(numberQuestions, 'div');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
import { expect, test } from "@odoo/hoot";
|
||||
import {
|
||||
contains,
|
||||
defineModels,
|
||||
fields,
|
||||
makeServerError,
|
||||
models,
|
||||
mountView,
|
||||
onRpc,
|
||||
} from "@web/../tests/web_test_helpers";
|
||||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
import { animationFrame, press, queryAll, queryOne } from "@odoo/hoot-dom";
|
||||
|
||||
class Survey extends models.Model {
|
||||
question_and_page_ids = fields.One2many({ relation: "survey_question" });
|
||||
favorite_color = fields.Char({ string: "Favorite color" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
question_and_page_ids: [1, 2],
|
||||
favorite_color: "",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
class SurveyQuestion extends models.Model {
|
||||
_name = "survey_question";
|
||||
|
||||
is_page = fields.Boolean();
|
||||
title = fields.Char();
|
||||
random_questions_count = fields.Integer({ string: "Question Count" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
is_page: true,
|
||||
title: "firstSectionTitle",
|
||||
random_questions_count: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
is_page: false,
|
||||
title: "recordTitle",
|
||||
random_questions_count: 5,
|
||||
},
|
||||
];
|
||||
_views = {
|
||||
form: /* xml */ `
|
||||
<form>
|
||||
<field name="title" />
|
||||
</form>
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
defineModels([Survey, SurveyQuestion]);
|
||||
defineMailModels();
|
||||
|
||||
test("basic rendering", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
expect(".o_field_x2many .o_list_renderer table.o_section_list_view").toHaveCount(1);
|
||||
expect(".o_data_row").toHaveCount(2);
|
||||
const rows = queryAll(".o_data_row");
|
||||
expect(rows[0]).toHaveClass("o_is_section fw-bold");
|
||||
expect(rows[0]).toHaveText("firstSectionTitle 4");
|
||||
expect(rows[1]).toHaveText("recordTitle 5");
|
||||
expect(queryOne("td[name=title]", { root: rows[0] })).toHaveAttribute("colspan", "1");
|
||||
expect(queryOne("td[name=title]", { root: rows[1] })).not.toHaveAttribute("colspan");
|
||||
});
|
||||
|
||||
test("click on section behaves as usual in readonly mode", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
readonly: true,
|
||||
});
|
||||
|
||||
await contains(".o_data_cell").click();
|
||||
expect(".o_selected_row").toHaveCount(0);
|
||||
expect(".modal .o_form_view").toHaveCount(1);
|
||||
});
|
||||
|
||||
test("click on section edit the section in place", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>`,
|
||||
});
|
||||
await contains(".o_data_cell").click();
|
||||
expect(".o_is_section").toHaveClass("o_selected_row");
|
||||
expect(".modal .o_form_view").toHaveCount(0);
|
||||
});
|
||||
|
||||
test("click on real line saves form and opens a dialog", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="favorite_color"/>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
onRpc("survey", "web_save", () => {
|
||||
expect.step("save parent form");
|
||||
});
|
||||
await contains("[name='favorite_color'] input").edit("Yellow");
|
||||
await contains(".o_data_row:nth-child(2) .o_data_cell").click();
|
||||
// Edit content to trigger the expected actual save at row opening
|
||||
expect.verifySteps(["save parent form"]);
|
||||
expect(".o_selected_row").toHaveCount(1);
|
||||
expect(".modal .o_form_view").toHaveCount(1);
|
||||
});
|
||||
|
||||
test("A validation error from saving parent form notifies and prevents dialog from closing", async () => {
|
||||
expect.errors(1);
|
||||
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
const error = makeServerError({
|
||||
description: "This isn't right!",
|
||||
type: "ValidationError",
|
||||
});
|
||||
onRpc("survey", "web_save", () => {
|
||||
expect.step("save parent form");
|
||||
throw error;
|
||||
});
|
||||
await contains(".o_data_row:nth-child(2) .o_data_cell").click();
|
||||
await contains(".o_dialog:not(.o_inactive_modal) .modal-body [name='title'] input").edit(
|
||||
"Invalid RecordTitle"
|
||||
);
|
||||
await contains(".o_dialog:not(.o_inactive_modal) .o_form_button_save").click();
|
||||
expect.verifySteps(["save parent form"]);
|
||||
expect.verifyErrors(["This isn't right!"]);
|
||||
await animationFrame();
|
||||
expect(".o_notification").toHaveCount(1);
|
||||
expect(".modal .o_form_view").toHaveCount(1);
|
||||
expect(".modal-dialog .o_form_button_save").toHaveCount(1);
|
||||
expect(".modal-dialog .o_form_button_save[disabled='1']").toHaveCount(0);
|
||||
});
|
||||
|
||||
test.tags("desktop");
|
||||
test("can create section inline", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
<control>
|
||||
<create string="add line" />
|
||||
<create string="add section" context="{'default_is_page': true}" />
|
||||
</control>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
|
||||
expect(".o_selected_row").toHaveCount(0);
|
||||
|
||||
await contains(".o_field_x2many_list_row_add a:eq(1)").click();
|
||||
expect(".o_selected_row.o_is_section").toHaveCount(1);
|
||||
expect(".modal .o_form_view").toHaveCount(0);
|
||||
});
|
||||
|
||||
test("creates real record in form dialog", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
<control>
|
||||
<create string="add line" />
|
||||
<create string="add section" context="{'default_is_page': true}" />
|
||||
</control>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
|
||||
await contains(".o_field_x2many_list_row_add a").click();
|
||||
expect(".o_selected_row").toHaveCount(0);
|
||||
expect(".modal .o_form_view").toHaveCount(1);
|
||||
});
|
||||
|
||||
test("press enter with focus in a edited section pass the section in readonly mode", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids" widget="question_page_one2many">
|
||||
<list>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
await contains(".o_data_row .o_data_cell").click();
|
||||
expect(".o_selected_row.o_is_section").toHaveCount(1);
|
||||
|
||||
await contains("[name='title'] input").edit("a");
|
||||
|
||||
press("Enter");
|
||||
expect(".o_selected_row.o_is_section").toHaveCount(0);
|
||||
expect(".o_is_section [name=title]").toHaveText("a");
|
||||
});
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { click, editInput, getFixture, nextTick, triggerHotkey } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
QUnit.module("QuestionPageOneToManyField", (hooks) => {
|
||||
let serverData;
|
||||
let target;
|
||||
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
fields: { lines: { type: "one2many", relation: "lines_sections" } },
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
lines: [1, 2],
|
||||
},
|
||||
],
|
||||
},
|
||||
lines_sections: {
|
||||
fields: {
|
||||
is_page: { type: "boolean" },
|
||||
title: { type: "char", string: "Title" },
|
||||
random_questions_count: { type: "number", string: "Question Count" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
is_page: true,
|
||||
title: "firstSectionTitle",
|
||||
random_questions_count: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
is_page: false,
|
||||
title: "recordTitle",
|
||||
random_questions_count: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
views: {
|
||||
"lines_sections,false,form": `
|
||||
<form>
|
||||
<field name="title" />
|
||||
</form>
|
||||
`,
|
||||
},
|
||||
};
|
||||
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.test("basic rendering", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsOnce(target, ".o_field_x2many .o_list_renderer table.o_section_list_view");
|
||||
assert.containsN(target, ".o_data_row", 2);
|
||||
const rows = target.querySelectorAll(".o_data_row");
|
||||
assert.hasClass(rows[0], "o_is_section");
|
||||
assert.hasClass(rows[0], "fw-bold");
|
||||
assert.strictEqual(rows[0].textContent, "firstSectionTitle4");
|
||||
assert.strictEqual(rows[1].textContent, "recordTitle5");
|
||||
assert.strictEqual(rows[0].querySelector("td[name=title]").getAttribute("colspan"), "1");
|
||||
assert.strictEqual(rows[1].querySelector("td[name=title]").getAttribute("colspan"), null);
|
||||
});
|
||||
|
||||
QUnit.test("click on section behaves as usual in readonly mode", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
mode: "readonly",
|
||||
});
|
||||
|
||||
await click(target.querySelector(".o_data_cell"));
|
||||
assert.containsNone(target, ".o_selected_row");
|
||||
assert.containsOnce(target, ".modal .o_form_view");
|
||||
});
|
||||
|
||||
QUnit.test("click on section edit the section in place", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>`,
|
||||
});
|
||||
await click(target.querySelector(".o_data_cell"));
|
||||
assert.hasClass(target.querySelector(".o_is_section"), "o_selected_row");
|
||||
assert.containsNone(target, ".modal .o_form_view");
|
||||
});
|
||||
|
||||
QUnit.test("click on real line opens a dialog", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
await click(target.querySelector(".o_data_row:nth-child(2) .o_data_cell"));
|
||||
assert.containsNone(target, ".o_selected_row");
|
||||
assert.containsOnce(target, ".modal .o_form_view");
|
||||
});
|
||||
|
||||
QUnit.test("can create section inline", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
<control>
|
||||
<create string="add line" />
|
||||
<create string="add section" context="{'default_is_page': true}" />
|
||||
</control>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
|
||||
assert.containsNone(target, ".o_selected_row");
|
||||
|
||||
await click(target.querySelectorAll(".o_field_x2many_list_row_add a")[1]);
|
||||
assert.containsOnce(target, ".o_selected_row.o_is_section");
|
||||
assert.containsNone(target, ".modal .o_form_view");
|
||||
});
|
||||
|
||||
QUnit.test("creates real record in form dialog", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
<control>
|
||||
<create string="add line" />
|
||||
<create string="add section" context="{'default_is_page': true}" />
|
||||
</control>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
|
||||
await click(target.querySelector(".o_field_x2many_list_row_add a"));
|
||||
assert.containsNone(target, ".o_selected_row");
|
||||
assert.containsOnce(target, ".modal .o_form_view");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"press enter with focus in a edited section pass the section in readonly mode",
|
||||
async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="question_page_one2many">
|
||||
<tree>
|
||||
<field name="is_page" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="random_questions_count" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
await click(target.querySelector(".o_data_row .o_data_cell"));
|
||||
assert.containsOnce(target, ".o_selected_row.o_is_section");
|
||||
|
||||
await editInput(target, "[name='title'] input", "a");
|
||||
|
||||
triggerHotkey("Enter");
|
||||
await nextTick();
|
||||
|
||||
assert.containsNone(target, ".o_selected_row.o_is_section");
|
||||
assert.strictEqual(target.querySelector(".o_is_section [name=title]").innerText, "a");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
import { expect, test } from "@odoo/hoot";
|
||||
import { animationFrame } from "@odoo/hoot-dom";
|
||||
import { contains, defineModels, fields, models, mountView } from "@web/../tests/web_test_helpers";
|
||||
|
||||
class Survey extends models.Model {
|
||||
question_and_page_ids = fields.One2many({ relation: "survey_question" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
question_and_page_ids: [1, 2],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
class SurveyQuestion extends models.Model {
|
||||
_name = "survey_question";
|
||||
|
||||
title = fields.Char();
|
||||
sequence = fields.Integer();
|
||||
triggering_question_ids = fields.Many2many({
|
||||
string: "Triggering question",
|
||||
relation: "survey_question",
|
||||
required: false,
|
||||
});
|
||||
triggering_answer_ids = fields.Many2many({
|
||||
string: "Triggering answers",
|
||||
relation: "survey_question_answer",
|
||||
required: false,
|
||||
});
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
sequence: 1,
|
||||
title: "Question 1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
sequence: 2,
|
||||
title: "Question 2",
|
||||
triggering_question_ids: [1],
|
||||
triggering_answer_ids: [1],
|
||||
},
|
||||
];
|
||||
_views = {
|
||||
form: /* xml */ `
|
||||
<form>
|
||||
<group>
|
||||
<field name="title"/>
|
||||
<field name="triggering_question_ids" invisible="1"/>
|
||||
<field name="triggering_answer_ids" invisible="1" widget="many2many_tags"/>
|
||||
</group>
|
||||
</form>
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
class SurveyQuestionAnswer extends models.Model {
|
||||
_name = "survey_question_answer";
|
||||
|
||||
name = fields.Char();
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Question 1: Answer 1",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
defineModels([Survey, SurveyQuestion, SurveyQuestionAnswer]);
|
||||
defineMailModels();
|
||||
|
||||
test("dynamic rendering of surveyQuestionTriggerError rows", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="question_and_page_ids">
|
||||
<list>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title"/>
|
||||
<field name="triggering_question_ids" invisible="1"/>
|
||||
<field name="triggering_answer_ids" invisible="1" widget="many2many_tags"/> <!-- widget to fetch display_name -->
|
||||
<widget name="survey_question_trigger"/>
|
||||
</list>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
|
||||
const firstDataRow = ".o_data_row:eq(0)";
|
||||
const secondDataRow = ".o_data_row:eq(1)";
|
||||
const q1TriggerDiv = `${firstDataRow} td.o_data_cell div.o_widget_survey_question_trigger`;
|
||||
const q2TriggerDiv = `${secondDataRow} td.o_data_cell div.o_widget_survey_question_trigger`;
|
||||
|
||||
expect(".o_field_x2many .o_list_renderer table.o_list_table").toHaveCount(1);
|
||||
expect(".o_data_row").toHaveCount(2);
|
||||
|
||||
expect(firstDataRow).toHaveText("Question 1");
|
||||
expect(`${q1TriggerDiv} button`).toHaveCount(0);
|
||||
|
||||
expect(secondDataRow).toHaveText("Question 2");
|
||||
expect(`${q2TriggerDiv} button`).toHaveCount(1);
|
||||
// Question 2 is correctly placed after Question 1
|
||||
expect(`${q2TriggerDiv} button i`).not.toHaveClass("text-warning");
|
||||
expect(`${q2TriggerDiv} button i`).toHaveAttribute(
|
||||
"data-tooltip",
|
||||
'Displayed if "Question 1: Answer 1".',
|
||||
{ message: "Trigger tooltip should be 'Displayed if \"Question 1: Answer 1\".'." }
|
||||
);
|
||||
|
||||
// drag and drop Question 2 (triggered) before Question 1 (trigger)
|
||||
await contains("tbody tr:nth-child(2) .o_handle_cell").dragAndDrop("tbody tr:nth-child(1)");
|
||||
await animationFrame();
|
||||
|
||||
expect(firstDataRow).toHaveText("Question 2");
|
||||
expect(`${q1TriggerDiv} button`).toHaveCount(1);
|
||||
expect(`${q1TriggerDiv} button i`).toHaveClass("text-warning");
|
||||
expect(`${q1TriggerDiv} button i`).toHaveAttribute(
|
||||
"data-tooltip",
|
||||
'⚠ Triggers based on the following questions will not work because they are positioned after this question:\n"Question 1".',
|
||||
{ message: "Trigger tooltip should have been changed to misplacement error message." }
|
||||
);
|
||||
|
||||
// drag and drop Question 1 (trigger) back before Question 2 (triggered)
|
||||
await contains("tbody tr:nth-child(2) .o_handle_cell").dragAndDrop("tbody tr:nth-child(1)");
|
||||
await animationFrame();
|
||||
|
||||
expect(".o_data_row:eq(1)").toHaveText("Question 2");
|
||||
expect(`${q2TriggerDiv} button i`).not.toHaveClass("text-warning");
|
||||
expect(`${q2TriggerDiv} button i`).toHaveAttribute(
|
||||
"data-tooltip",
|
||||
'Displayed if "Question 1: Answer 1".',
|
||||
{ message: "Trigger tooltip should be back to 'Displayed if \"Question 1: Answer 1\".'." }
|
||||
);
|
||||
});
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
import { expect, test } from "@odoo/hoot";
|
||||
import { animationFrame, manuallyDispatchProgrammaticEvent, queryOne } from "@odoo/hoot-dom";
|
||||
import {
|
||||
contains,
|
||||
defineModels,
|
||||
fields,
|
||||
models,
|
||||
mountView,
|
||||
onRpc,
|
||||
} from "@web/../tests/web_test_helpers";
|
||||
|
||||
class Survey extends models.Model {
|
||||
question_and_page_ids = fields.One2many({ relation: "survey_question" });
|
||||
session_speed_rating = fields.Boolean({ string: "Speed Reward", onChange: () => {} });
|
||||
session_speed_rating_time_limit = fields.Integer({
|
||||
string: "Speed Reward Time (s)",
|
||||
onChange: () => {},
|
||||
});
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
question_and_page_ids: [1],
|
||||
session_speed_rating: false,
|
||||
session_speed_rating_time_limit: 30,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
class SurveyQuestion extends models.Model {
|
||||
_name = "survey_question";
|
||||
|
||||
title = fields.Char();
|
||||
is_time_customized = fields.Boolean({ string: "Is time customized" });
|
||||
is_time_limited = fields.Boolean({ string: "Is time limited" });
|
||||
survey_id = fields.Many2one({ relation: "survey", string: "Survey" });
|
||||
time_limit = fields.Integer({ string: "Time limit (s)" });
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
is_time_customized: false,
|
||||
is_time_limited: false,
|
||||
survey_id: 1,
|
||||
time_limit: 30,
|
||||
title: "Question 1",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
defineModels([Survey, SurveyQuestion]);
|
||||
defineMailModels();
|
||||
|
||||
test("Auto update of is_time_customized", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "survey",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<group>
|
||||
<field name="session_speed_rating"/>
|
||||
<field name="session_speed_rating_time_limit"/>
|
||||
</group>
|
||||
<field name="question_and_page_ids" no-label="1" mode="list">
|
||||
<list>
|
||||
<field name="title"/>
|
||||
<field name="is_time_limited"/>
|
||||
<field name="time_limit"/>
|
||||
<field name="is_time_customized"/>
|
||||
</list>
|
||||
<form>
|
||||
<group>
|
||||
<field name="is_time_customized"/>
|
||||
<field name="is_time_limited" readonly="0"
|
||||
widget="boolean_update_flag"
|
||||
options="{'flagFieldName': 'is_time_customized'}"
|
||||
context="{'referenceValue': parent.session_speed_rating}"/>
|
||||
<field name="time_limit" readonly="0"
|
||||
widget="integer_update_flag"
|
||||
options="{'flagFieldName': 'is_time_customized'}"
|
||||
context="{'referenceValue': parent.session_speed_rating_time_limit}"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
onRpc("survey", "onchange", () => ({
|
||||
value: { question_and_page_ids: [[1, 1, { is_time_customized: false }]] },
|
||||
}));
|
||||
// Open question
|
||||
await contains("tr.o_data_row > td.o_list_char").click();
|
||||
expect("div[name='is_time_customized'] input").not.toBeChecked();
|
||||
// set question "is_time_limited" => true
|
||||
await contains("div[name='is_time_limited'] input").click();
|
||||
await animationFrame();
|
||||
expect("div[name='is_time_customized'] input").toBeChecked(); // widget-triggered update to `true` based on `is_time_limited`
|
||||
// save question
|
||||
await contains("div.modal-dialog button.o_form_button_save").click();
|
||||
await animationFrame();
|
||||
// set survey "session_speed_rating" => true
|
||||
await contains("div[name='session_speed_rating'] input").click();
|
||||
await animationFrame();
|
||||
// check that questions "is_time_limited" === true and "is_time_customized" === false after survey onchange
|
||||
expect("td.o_field_cell[name='is_time_limited'] input").toBeChecked();
|
||||
expect("td.o_field_cell[name='is_time_customized'] input").not.toBeChecked();
|
||||
// Open question again
|
||||
await contains("tr.o_data_row > td.o_list_char").click();
|
||||
await contains("div[name='time_limit'] input").edit(20);
|
||||
// TODO: JUM (events concurrency)
|
||||
await manuallyDispatchProgrammaticEvent(queryOne("div[name='time_limit'] input"), "change");
|
||||
await animationFrame();
|
||||
expect("div[name='is_time_customized'] input").toBeChecked(); // widget-triggered update to `true` based on `time_limit`
|
||||
await contains("div[name='time_limit'] input").edit(30);
|
||||
// TODO: JUM (events concurrency)
|
||||
await manuallyDispatchProgrammaticEvent(queryOne("div[name='time_limit'] input"), "change");
|
||||
await animationFrame();
|
||||
expect("div[name='is_time_customized'] input").not.toBeChecked(); // widget-triggered update to `false` based on `time_limit`
|
||||
// set question "is_time_limited" => false
|
||||
await contains("div[name='is_time_limited'] input").click();
|
||||
await animationFrame();
|
||||
expect("div[name='is_time_customized'] input").toBeChecked(); // widget-triggered update to `false` based on `is_time_limited`
|
||||
});
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
import { expect, test } from "@odoo/hoot";
|
||||
import { animationFrame, click } from "@odoo/hoot-dom";
|
||||
import { defineModels, fields, models, mountView } from "@web/../tests/web_test_helpers";
|
||||
|
||||
class Partner extends models.Model {
|
||||
is_raining_outside = fields.Boolean();
|
||||
mood = fields.Selection({
|
||||
selection: [
|
||||
["happy", "Happy"],
|
||||
["sad", "Sad"],
|
||||
],
|
||||
});
|
||||
color = fields.Selection({
|
||||
selection: [
|
||||
["white", "White"],
|
||||
["grey", "Grey"],
|
||||
["black", "Black"],
|
||||
],
|
||||
});
|
||||
allowed_colors = fields.Json();
|
||||
allowed_moods = fields.Json();
|
||||
|
||||
_onChanges = {
|
||||
is_raining_outside(record) {
|
||||
record.allowed_moods = ["happy"] + (record.is_raining_outside ? ["sad"] : []);
|
||||
},
|
||||
color(record) {
|
||||
record.allowed_moods =
|
||||
(record.color !== "black" ? ["happy"] : []) +
|
||||
(record.color !== "white" ? ["sad"] : []);
|
||||
},
|
||||
mood(record) {
|
||||
record.allowed_colors =
|
||||
(record.mood === "happy" ? ["white"] : []) +
|
||||
["grey"] +
|
||||
(record.mood === "sad" ? ["black"] : []);
|
||||
},
|
||||
};
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
allowed_colors: "['white', 'grey']",
|
||||
allowed_moods: "['happy']",
|
||||
display_name: "first record",
|
||||
is_raining_outside: false,
|
||||
mood: "happy",
|
||||
color: "white",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
defineMailModels();
|
||||
defineModels([Partner]);
|
||||
|
||||
const formArchColorsOnly = /* xml */ `
|
||||
<form>
|
||||
<field name="is_raining_outside"/>
|
||||
<field name="allowed_colors" invisible="1"/>
|
||||
<field name="color" widget="radio_selection_with_filter"
|
||||
options="{'allowed_selection_field': 'allowed_colors'}"/>
|
||||
</form>
|
||||
`;
|
||||
|
||||
const formArchFull = /* xml */ `
|
||||
<form>
|
||||
<field name="is_raining_outside"/>
|
||||
<field name="allowed_moods" invisible="1"/>
|
||||
<field name="allowed_colors" invisible="1"/>
|
||||
<field name="mood" widget="radio_selection_with_filter"
|
||||
options="{'allowed_selection_field': 'allowed_moods'}"/>
|
||||
<field name="color" widget="radio_selection_with_filter"
|
||||
options="{'allowed_selection_field': 'allowed_colors'}"/>
|
||||
</form>
|
||||
`;
|
||||
|
||||
test("radio selection field with filter, empty list", async () => {
|
||||
Partner._records[0].allowed_colors = [];
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: formArchColorsOnly,
|
||||
});
|
||||
|
||||
expect(".o_selection_badge").toHaveCount(0);
|
||||
});
|
||||
|
||||
test("radio selection field with filter, single choice", async () => {
|
||||
Partner._records[0].allowed_colors = ["grey"];
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: formArchColorsOnly,
|
||||
});
|
||||
|
||||
expect(".o_radio_input").toHaveCount(1);
|
||||
expect("input[data-value='white']").toHaveCount(0);
|
||||
expect("input[data-value='grey']").toBeVisible();
|
||||
expect("input[data-value='black']").toHaveCount(0);
|
||||
});
|
||||
|
||||
test("radio selection field with filter, all choices", async () => {
|
||||
Partner._records[0].allowed_colors = ["white", "grey", "black"];
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: formArchColorsOnly,
|
||||
});
|
||||
|
||||
expect(".o_radio_input").toHaveCount(3);
|
||||
expect("input[data-value='white']").toBeVisible();
|
||||
expect("input[data-value='grey']").toBeVisible();
|
||||
expect("input[data-value='black']").toBeVisible();
|
||||
});
|
||||
|
||||
test("radio selection field with filter, synchronize with other field", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: formArchFull,
|
||||
});
|
||||
// not raining outside => sad should be invisible
|
||||
expect("[name='is_raining_outside'] input").not.toBeChecked();
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(1);
|
||||
expect("input[data-value='happy']").toBeVisible();
|
||||
expect("input[data-value='sad']").toHaveCount(0);
|
||||
|
||||
await click("[name='is_raining_outside'] input");
|
||||
await animationFrame();
|
||||
|
||||
// raining outside => sad should be visible
|
||||
expect("[name='is_raining_outside'] input").toBeChecked();
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(2);
|
||||
expect("input[data-value='happy']").toBeVisible();
|
||||
expect("input[data-value='sad']").toBeVisible();
|
||||
|
||||
await click("[name='is_raining_outside'] input");
|
||||
await animationFrame();
|
||||
|
||||
// not raining outside => sad should be invisible
|
||||
expect("[name='is_raining_outside'] input").not.toBeChecked();
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(1);
|
||||
expect("input[data-value='happy']").toBeVisible();
|
||||
expect("input[data-value='sad']").toHaveCount(0);
|
||||
});
|
||||
|
||||
test("radio selection field with filter, cross radio synchronization", async () => {
|
||||
await mountView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: formArchFull,
|
||||
});
|
||||
|
||||
// happy and white by default, sad and black should be invisible
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(1);
|
||||
expect("div[name='color'] .o_radio_input").toHaveCount(2);
|
||||
expect("input[data-value='happy']").toBeVisible();
|
||||
expect("input[data-value='sad']").toHaveCount(0);
|
||||
expect("input[data-value='white']").toBeVisible();
|
||||
expect("input[data-value='grey']").toBeVisible();
|
||||
expect("input[data-value='black']").toHaveCount(0);
|
||||
|
||||
await click("[name='color'] input[data-value='grey']");
|
||||
await animationFrame();
|
||||
|
||||
// happy and grey, sad should be revealed
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(2);
|
||||
expect("div[name='color'] .o_radio_input").toHaveCount(2);
|
||||
expect("input[data-value='happy']").toBeVisible();
|
||||
expect("input[data-value='sad']").toBeVisible();
|
||||
expect("input[data-value='white']").toBeVisible();
|
||||
expect("input[data-value='grey']").toBeVisible();
|
||||
expect("input[data-value='black']").toHaveCount(0);
|
||||
|
||||
await click("div[name='mood'] input[data-value='sad']");
|
||||
await animationFrame();
|
||||
|
||||
// sad and grey, white should disappear and black should appear
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(2);
|
||||
expect("div[name='color'] .o_radio_input").toHaveCount(2);
|
||||
expect("input[data-value='happy']").toBeVisible();
|
||||
expect("input[data-value='sad']").toBeVisible();
|
||||
expect("input[data-value='white']").toHaveCount(0);
|
||||
expect("input[data-value='grey']").toBeVisible();
|
||||
expect("input[data-value='black']").toBeVisible();
|
||||
|
||||
await click("div[name='color'] input[data-value='black']");
|
||||
await animationFrame();
|
||||
|
||||
// sad and black, happy should disappear
|
||||
expect("div[name='mood'] .o_radio_input").toHaveCount(1);
|
||||
expect("div[name='color'] .o_radio_input").toHaveCount(2);
|
||||
expect("input[data-value='happy']").toHaveCount(0);
|
||||
expect("input[data-value='sad']").toBeVisible();
|
||||
expect("input[data-value='white']").toHaveCount(0);
|
||||
expect("input[data-value='grey']").toBeVisible();
|
||||
expect("input[data-value='black']").toBeVisible();
|
||||
});
|
||||
|
|
@ -1,109 +1,194 @@
|
|||
odoo.define('survey.tour_test_certification_failure', function (require) {
|
||||
'use strict';
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
|
||||
var SurveyFormWidget = require('survey.form');
|
||||
/**
|
||||
* Speed up fade-in fade-out to avoid useless delay in tests.
|
||||
*/
|
||||
SurveyFormWidget.include({
|
||||
_submitForm: function () {
|
||||
this.fadeInOutDelay = 0;
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
function patchSurveyForm() {
|
||||
const SurveyForm = odoo.loader.modules.get("@survey/interactions/survey_form").SurveyForm;
|
||||
patch(SurveyForm.prototype, {
|
||||
submitForm() {
|
||||
this.fadeInOutDelay = 0;
|
||||
return super.submitForm(...arguments);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This tour will test that, for the demo certification allowing 2 attempts, a user can
|
||||
* try and fail twice and will no longer be able to take the certification.
|
||||
*/
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
var failSteps = [{ // Page-1
|
||||
content: "Clicking on Start Certification",
|
||||
trigger: 'button.btn.btn-primary.btn-lg:contains("Start Certification")',
|
||||
}, { // Question: Do we sell Acoustic Bloc Screens?
|
||||
content: "Selecting answer 'No'",
|
||||
trigger: 'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("No")',
|
||||
}, { // Question: Select all the existing products
|
||||
content: "Ticking answer 'Fanta'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Fanta")'
|
||||
}, {
|
||||
content: "Ticking answer 'Drawer'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer")'
|
||||
}, {
|
||||
content: "Ticking answer 'Conference chair'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair")'
|
||||
}, { // Question: Select all the available customizations for our Customizable Desk
|
||||
content: "Ticking answer 'Color'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color")'
|
||||
}, {
|
||||
content: "Ticking answer 'Height'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Height")'
|
||||
}, { // Question: How many versions of the Corner Desk do we have?
|
||||
content: "Selecting answer '2'",
|
||||
trigger: 'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2")',
|
||||
}, { // Question: Do you think we have missing products in our catalog? (not rated)
|
||||
content: "Missing products",
|
||||
trigger: 'div.js_question-wrapper:contains("Do you think we have missing products in our catalog") textarea',
|
||||
run: "text I don't know products enough to be able to answer that",
|
||||
}, { // Page-2 Question: How much do we sell our Cable Management Box?
|
||||
content: "Selecting answer '$80'",
|
||||
trigger: 'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("$80")',
|
||||
}, { // Question: Select all the products that sell for $100 or more
|
||||
content: "Ticking answer 'Corner Desk Right Sit'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Corner Desk Right Sit")'
|
||||
}, {
|
||||
content: "Ticking answer 'Desk Combination'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Desk Combination")'
|
||||
}, {
|
||||
content: "Ticking answer 'Office Chair Black'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Office Chair Black")'
|
||||
}, { // Question: What do you think about our prices (not rated)?
|
||||
trigger: 'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Correctly priced")',
|
||||
}, { // Page-3 Question: How many days is our money-back guarantee?
|
||||
content: "Inputting answer '60'",
|
||||
trigger: 'div.js_question-wrapper:contains("How many days is our money-back guarantee") input',
|
||||
run: 'text 60'
|
||||
}, { // Question: If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it?
|
||||
content: "Inputting answer '01/06/2020'",
|
||||
trigger: 'div.js_question-wrapper:contains("If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it") input',
|
||||
run: 'text 01/06/2020'
|
||||
}, { // Question: If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire?
|
||||
content: "Inputting answer '01/06/2021 00:00:01'",
|
||||
trigger: 'div.js_question-wrapper:contains("If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire") input',
|
||||
run: 'text 01/06/2021 00:00:01'
|
||||
}, { // Question: What day to you think is best for us to start having an annual sale (not rated)?
|
||||
trigger: 'div.js_question-wrapper:contains("What day to you think is best for us to start having an annual sale (not rated)") input',
|
||||
}, { // Question: What day and time do you think most customers are most likely to call customer service (not rated)?
|
||||
trigger: 'div.js_question-wrapper:contains("What day and time do you think most customers are most likely to call customer service (not rated)") input',
|
||||
}, { // Question: How many chairs do you think we should aim to sell in a year (not rated)?
|
||||
content: "Inputting answer '0'",
|
||||
trigger: 'div.js_question-wrapper:contains("How many chairs do you think we should aim to sell in a year (not rated)") input',
|
||||
run: 'text 0'
|
||||
}, {
|
||||
content: "Finish Survey",
|
||||
trigger: 'button[type="submit"]',
|
||||
}];
|
||||
const patchSteps = [
|
||||
{
|
||||
content: "Patching Survey Form Interaction",
|
||||
trigger: "body",
|
||||
run: function () {
|
||||
patchSurveyForm();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
var retrySteps = [{
|
||||
trigger: 'a:contains("Retry")'
|
||||
}];
|
||||
const failSteps = [
|
||||
{
|
||||
// Page-1
|
||||
content: "Clicking on Start Certification",
|
||||
trigger: 'button.btn.btn-primary.btn-lg:contains("Start Certification")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Do we sell Acoustic Bloc Screens?
|
||||
content: "Selecting answer 'No'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("No")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Select all the existing products
|
||||
content: "Ticking answer 'Fanta'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the existing products") label:contains("Fanta")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Drawer'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Conference chair'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Select all the available customizations for our Customizable Desk
|
||||
content: "Ticking answer 'Color'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Height'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Height")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: How many versions of the Corner Desk do we have?
|
||||
content: "Selecting answer '2'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Do you think we have missing products in our catalog? (not rated)
|
||||
content: "Missing products",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Do you think we have missing products in our catalog") textarea',
|
||||
run: "edit I don't know products enough to be able to answer that",
|
||||
},
|
||||
{
|
||||
// Page-2 Question: How much do we sell our Cable Management Box?
|
||||
content: "Selecting answer '$80'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("$80")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Select all the products that sell for $100 or more
|
||||
content: "Ticking answer 'Corner Desk Right Sit'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Corner Desk Right Sit")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Desk Combination'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Desk Combination")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Office Chair Black'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Office Chair Black")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: What do you think about our prices (not rated)?
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Correctly priced")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Page-3 Question: How many days is our money-back guarantee?
|
||||
content: "Inputting answer '60'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many days is our money-back guarantee") input',
|
||||
run: "edit 60",
|
||||
},
|
||||
{
|
||||
// Question: If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it?
|
||||
content: "Inputting answer '01/06/2020'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it") input',
|
||||
run: "edit 01/06/2020",
|
||||
},
|
||||
{
|
||||
// Question: If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire?
|
||||
content: "Inputting answer '01/06/2021 00:00:01'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire") input',
|
||||
run: "edit 01/06/2021 00:00:01",
|
||||
},
|
||||
{
|
||||
// Question: What day to you think is best for us to start having an annual sale (not rated)?
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What day to you think is best for us to start having an annual sale (not rated)") input',
|
||||
run: "edit Test",
|
||||
},
|
||||
{
|
||||
// Question: What day and time do you think most customers are most likely to call customer service (not rated)?
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What day and time do you think most customers are most likely to call customer service (not rated)") input',
|
||||
run: "edit Test",
|
||||
},
|
||||
{
|
||||
// Question: How many chairs do you think we should aim to sell in a year (not rated)?
|
||||
content: "Inputting answer '0'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many chairs do you think we should aim to sell in a year (not rated)") input',
|
||||
run: "edit 0",
|
||||
},
|
||||
{
|
||||
content: "Finish Survey",
|
||||
trigger: 'button[type="submit"]',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Click on Submit",
|
||||
trigger: 'button.btn-primary:contains("Submit")',
|
||||
run: "click",
|
||||
},
|
||||
];
|
||||
|
||||
const retrySteps = [
|
||||
{
|
||||
trigger: 'a:contains("Retry")',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
];
|
||||
|
||||
var lastSteps = [{
|
||||
trigger: 'h1:contains("Thank you!")',
|
||||
run: function () {
|
||||
if ($('a:contains("Retry")').length === 0) {
|
||||
$('h1:contains("Thank you!")').addClass('tour_success');
|
||||
}
|
||||
}
|
||||
trigger: 'h1:contains("You scored")',
|
||||
}, {
|
||||
trigger: 'h1.tour_success',
|
||||
trigger: 'body:not(:has(a:contains("Retry")))',
|
||||
}];
|
||||
|
||||
tour.register('test_certification_failure', {
|
||||
test: true,
|
||||
url: '/survey/start/4ead4bc8-b8f2-4760-a682-1fde8daaaaac'
|
||||
}, [].concat(failSteps, retrySteps, failSteps, lastSteps));
|
||||
|
||||
registry.category("web_tour.tours").add("test_certification_failure", {
|
||||
url: "/survey/start/4ead4bc8-b8f2-4760-a682-1fde8daaaaac",
|
||||
steps: () => [].concat(patchSteps, failSteps, retrySteps, failSteps, lastSteps),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,100 +1,180 @@
|
|||
odoo.define('survey.tour_test_certification_success', function (require) {
|
||||
'use strict';
|
||||
import { registry } from "@web/core/registry";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
|
||||
var SurveyFormWidget = require('survey.form');
|
||||
/**
|
||||
* Speed up fade-in fade-out to avoid useless delay in tests.
|
||||
*/
|
||||
SurveyFormWidget.include({
|
||||
_submitForm: function () {
|
||||
this.fadeInOutDelay = 0;
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
|
||||
tour.register('test_certification_success', {
|
||||
test: true,
|
||||
url: '/survey/start/4ead4bc8-b8f2-4760-a682-1fde8daaaaac'
|
||||
},
|
||||
[{ // Page-1
|
||||
content: "Clicking on Start Certification",
|
||||
trigger: 'button.btn.btn-primary.btn-lg:contains("Start Certification")',
|
||||
}, { // Question: Do we sell Acoustic Bloc Screens?
|
||||
content: "Selecting answer 'Yes'",
|
||||
trigger: 'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("Yes")',
|
||||
}, { // Question: Select all the existing products
|
||||
content: "Ticking answer 'Chair floor protection'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Chair floor protection")'
|
||||
}, {
|
||||
content: "Ticking answer 'Drawer'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer")'
|
||||
}, {
|
||||
content: "Ticking answer 'Conference chair'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair")'
|
||||
}, { // Question: Select all the available customizations for our Customizable Desk
|
||||
content: "Ticking answer 'Color'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color")'
|
||||
}, {
|
||||
content: "Ticking answer 'Legs'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Legs")'
|
||||
}, { // Question: How many versions of the Corner Desk do we have?
|
||||
content: "Selecting answer '2'",
|
||||
trigger: 'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2")',
|
||||
}, { // Question: Do you think we have missing products in our catalog? (not rated)
|
||||
content: "Missing products",
|
||||
trigger: 'div.js_question-wrapper:contains("Do you think we have missing products in our catalog") textarea',
|
||||
run: "text I think we should make more versions of the customizable desk, it's such an amazing product!",
|
||||
}, { // Page-2 Question: How much do we sell our Cable Management Box?
|
||||
content: "Selecting answer '$80' (wrong one)",
|
||||
trigger: 'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("$80")',
|
||||
}, { // Question: Select all the products that sell for $100 or more
|
||||
content: "Ticking answer 'Corner Desk Right Sit'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Corner Desk Right Sit")'
|
||||
}, {
|
||||
content: "Ticking answer 'Desk Combination'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Desk Combination")'
|
||||
}, {
|
||||
content: "Ticking answer 'Large Desk'",
|
||||
trigger: 'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Large Desk")'
|
||||
}, { // Question: What do you think about our prices (not rated)?
|
||||
content: "Selecting answer 'Underpriced'",
|
||||
trigger: 'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Underpriced")',
|
||||
}, { // Page-3 Question: How many days is our money-back guarantee?
|
||||
content: "Inputting answer '30'",
|
||||
trigger: 'div.js_question-wrapper:contains("How many days is our money-back guarantee") input',
|
||||
run: 'text 30'
|
||||
}, { // Question: If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it?
|
||||
content: "Inputting answer '01/08/2020'",
|
||||
trigger: 'div.js_question-wrapper:contains("If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it") input',
|
||||
run: 'text 01/08/2020'
|
||||
}, { // Question: If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire?
|
||||
content: "Inputting answer '01/07/2021 00:00:01'",
|
||||
trigger: 'div.js_question-wrapper:contains("If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire") input',
|
||||
run: 'text 01/07/2021 00:00:01'
|
||||
}, { // Question: What day to you think is best for us to start having an annual sale (not rated)?
|
||||
content: "Inputting answer '01/01/2021'",
|
||||
trigger: 'div.js_question-wrapper:contains("What day to you think is best for us to start having an annual sale (not rated)") input',
|
||||
run: 'text 01/01/2021'
|
||||
}, { // Question: What day and time do you think most customers are most likely to call customer service (not rated)?
|
||||
content: "Inputting answer '01/01/2021 13:00:01'",
|
||||
trigger: 'div.js_question-wrapper:contains("What day and time do you think most customers are most likely to call customer service (not rated)") input',
|
||||
run: 'text 01/01/2021 13:00:01'
|
||||
}, { // Question: How many chairs do you think we should aim to sell in a year (not rated)?
|
||||
content: "Inputting answer '1000'",
|
||||
trigger: 'div.js_question-wrapper:contains("How many chairs do you think we should aim to sell in a year (not rated)") input',
|
||||
run: 'text 1000'
|
||||
}, {
|
||||
content: "Finish Survey",
|
||||
trigger: 'button[type="submit"]',
|
||||
}, {
|
||||
content: "Thank you",
|
||||
trigger: 'h1:contains("Thank you!")',
|
||||
}, {
|
||||
content: "test passed",
|
||||
trigger: 'div:contains("Congratulations, you have passed the test!")',
|
||||
}
|
||||
]);
|
||||
|
||||
function patchSurveyForm() {
|
||||
const SurveyForm = odoo.loader.modules.get("@survey/interactions/survey_form").SurveyForm;
|
||||
patch(SurveyForm.prototype, {
|
||||
submitForm() {
|
||||
this.fadeInOutDelay = 0;
|
||||
return super.submitForm(...arguments);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
registry.category("web_tour.tours").add("test_certification_success", {
|
||||
url: "/survey/start/4ead4bc8-b8f2-4760-a682-1fde8daaaaac",
|
||||
steps: () => [
|
||||
{
|
||||
content: "Patching Survey Form Interaction",
|
||||
trigger: "body",
|
||||
run: function () {
|
||||
patchSurveyForm();
|
||||
},
|
||||
},
|
||||
{
|
||||
// Page-1
|
||||
content: "Clicking on Start Certification",
|
||||
trigger: 'button.btn.btn-primary.btn-lg:contains("Start Certification")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Do we sell Acoustic Bloc Screens?
|
||||
content: "Selecting answer 'Yes'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("Yes")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Select all the existing products
|
||||
content: "Ticking answer 'Chair floor protection'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the existing products") label:contains("Chair floor protection")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Drawer'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Conference chair'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Select all the available customizations for our Customizable Desk
|
||||
content: "Ticking answer 'Color'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Legs'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Legs")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: How many versions of the Corner Desk do we have?
|
||||
content: "Selecting answer '2'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Do you think we have missing products in our catalog? (not rated)
|
||||
content: "Missing products",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Do you think we have missing products in our catalog") textarea',
|
||||
run: "edit I think we should make more versions of the customizable desk, it's such an amazing product!",
|
||||
},
|
||||
{
|
||||
// Page-2 Question: How much do we sell our Cable Management Box?
|
||||
content: "Selecting answer '$80' (wrong one)",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("$80")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: Select all the products that sell for $100 or more
|
||||
content: "Ticking answer 'Corner Desk Right Sit'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Corner Desk Right Sit")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Desk Combination'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Desk Combination")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Ticking answer 'Large Desk'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Select all the products that sell for $100 or more") label:contains("Large Desk")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Question: What do you think about our prices (not rated)?
|
||||
content: "Selecting answer 'Underpriced'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Underpriced")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
// Page-3 Question: How many days is our money-back guarantee?
|
||||
content: "Inputting answer '30'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many days is our money-back guarantee") input',
|
||||
run: "edit 30",
|
||||
},
|
||||
{
|
||||
// Question: If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it?
|
||||
content: "Inputting answer '01/08/2020'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("If a customer purchases a product on 6 January 2020, what is the latest day we expect to ship it") input',
|
||||
run: "edit 01/08/2020",
|
||||
},
|
||||
{
|
||||
// Question: If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire?
|
||||
content: "Inputting answer '01/07/2021 00:00:01'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("If a customer purchases a 1 year warranty on 6 January 2020, when do we expect the warranty to expire") input',
|
||||
run: "edit 01/07/2021 00:00:01",
|
||||
},
|
||||
{
|
||||
// Question: What day to you think is best for us to start having an annual sale (not rated)?
|
||||
content: "Inputting answer '01/01/2021'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What day to you think is best for us to start having an annual sale (not rated)") input',
|
||||
run: "edit 01/01/2021",
|
||||
},
|
||||
{
|
||||
// Question: What day and time do you think most customers are most likely to call customer service (not rated)?
|
||||
content: "Inputting answer '01/01/2021 13:00:01'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What day and time do you think most customers are most likely to call customer service (not rated)") input',
|
||||
run: "edit 01/01/2021 13:00:01",
|
||||
},
|
||||
{
|
||||
// Question: How many chairs do you think we should aim to sell in a year (not rated)?
|
||||
content: "Inputting answer '1000'",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many chairs do you think we should aim to sell in a year (not rated)") input',
|
||||
run: "edit 1000",
|
||||
},
|
||||
{
|
||||
content: "Finish Survey",
|
||||
trigger: 'button[type="submit"]',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Click on Submit",
|
||||
trigger: 'button.btn-primary:contains("Submit")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "You scored",
|
||||
trigger: 'h1:contains("You scored")',
|
||||
},
|
||||
{
|
||||
content: "test passed",
|
||||
trigger: 'div:contains("Congratulations, you have passed the test!")',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,70 +1,138 @@
|
|||
odoo.define('survey.tour_test_survey', function (require) {
|
||||
'use strict';
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
|
||||
tour.register('test_survey', {
|
||||
test: true,
|
||||
url: '/survey/start/b137640d-14d4-4748-9ef6-344caaaaaae',
|
||||
}, [
|
||||
const survey_steps = (checkPageTranslation) => [
|
||||
// Page-1
|
||||
{
|
||||
content: 'Click on Start',
|
||||
trigger: 'button.btn:contains("Start")',
|
||||
}, {
|
||||
run: "click",
|
||||
}, ...(checkPageTranslation ? checkPageTranslation : []), {
|
||||
content: 'Answer Where do you live',
|
||||
trigger: 'div.js_question-wrapper:contains("Where do you live") input',
|
||||
run: 'text Mordor-les-bains',
|
||||
run: "edit Mordor-les-bains",
|
||||
}, {
|
||||
content: 'Answer Where do you live',
|
||||
trigger: 'div.js_question-wrapper:contains("When is your date of birth") input',
|
||||
run: 'text 05/05/1980',
|
||||
run: "edit 05/05/1980",
|
||||
}, {
|
||||
content: 'Answer How frequently do you buy products online',
|
||||
trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online") label:contains("Once a month")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer How many times did you order products on our website',
|
||||
trigger: 'div.js_question-wrapper:contains("How many times did you order products on our website") input',
|
||||
run: 'text 12',
|
||||
run: "edit 12",
|
||||
}, {
|
||||
content: 'Submit and go to Next Page',
|
||||
trigger: 'button[value="next"]',
|
||||
run: "click",
|
||||
},
|
||||
// Page-2
|
||||
...(checkPageTranslation ? checkPageTranslation : []),
|
||||
{
|
||||
content: 'Answer Which of the following words would you use to describe our products (High Quality)',
|
||||
trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Which of the following words would you use to describe our products (Good value for money)',
|
||||
trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (The new layout and design is fresh and up-to-date)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") td:first',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (It is easy to find the product that I want)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") td:eq(2)',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (The tool to compare the products is useful to make a choice)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") td:eq(3)',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (The checkout process is clear and secure)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") td:eq(2)',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (I have added products to my wishlist)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") td:last',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Do you have any other comments, questions, or concerns',
|
||||
trigger: 'div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea',
|
||||
run: 'text This is great. Really.',
|
||||
run: "edit This is great. Really.",
|
||||
}, {
|
||||
content: 'Answer How would you rate your experience on our website?',
|
||||
trigger: 'div.js_question-wrapper:contains("How would you rate your experience on our website") label:contains("4")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Click Submit and finish the survey',
|
||||
trigger: 'button[value="finish"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Click on Submit",
|
||||
trigger: ".modal-footer button.btn-primary",
|
||||
run: "click",
|
||||
},
|
||||
// Final page
|
||||
{
|
||||
content: 'Thank you',
|
||||
trigger: 'h1:contains("Thank you!")',
|
||||
}
|
||||
]);
|
||||
];
|
||||
|
||||
registry.category("web_tour.tours").add("test_survey", {
|
||||
url: "/survey/start/b137640d-14d4-4748-9ef6-344caaaaaae",
|
||||
steps: () => [
|
||||
{
|
||||
content: "Check that the language selector is hidden",
|
||||
trigger: "select[name='lang_code'].d-none:not(:visible)",
|
||||
},
|
||||
...survey_steps(),
|
||||
],
|
||||
});
|
||||
|
||||
registry.category("web_tour.tours").add("test_survey_multilang", {
|
||||
url: "/survey/start/b137640d-14d4-4748-9ef6-344caaaaaae",
|
||||
steps: () => {
|
||||
return [
|
||||
{
|
||||
content: "Select French",
|
||||
trigger: "select[name='lang_code']",
|
||||
run() {
|
||||
const langSelect = document.querySelector("select[name='lang_code']");
|
||||
if (Array.from(langSelect.classList).includes("d-none")) {
|
||||
throw new Error("The language selector must not be hidden.");
|
||||
}
|
||||
langSelect.value = "fr_BE";
|
||||
langSelect.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
},
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Check French translation",
|
||||
trigger: "h1.o_survey_main_title:contains('Enquête de satisfaction')",
|
||||
},
|
||||
{
|
||||
content: "Select French",
|
||||
trigger: "select[name='lang_code']",
|
||||
run() {
|
||||
const langSelect = document.querySelector("select[name='lang_code']");
|
||||
langSelect.value = "fr_BE";
|
||||
langSelect.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
},
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Check French translation",
|
||||
trigger: "h1.o_survey_main_title:contains('Enquête de satisfaction')",
|
||||
},
|
||||
...survey_steps([
|
||||
{
|
||||
content: "Check Page translation",
|
||||
trigger: ".js_question-wrapper h3:contains('FR: ')",
|
||||
},
|
||||
]),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,60 +1,90 @@
|
|||
odoo.define('survey.tour_test_survey_chained_conditional_questions', function (require) {
|
||||
'use strict';
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
const tour = require('web_tour.tour');
|
||||
|
||||
tour.register('test_survey_chained_conditional_questions', {
|
||||
test: true,
|
||||
registry.category("web_tour.tours").add('test_survey_chained_conditional_questions', {
|
||||
url: '/survey/start/3cfadce3-3f7e-41da-920d-10fa0eb19527',
|
||||
}, [
|
||||
steps: () => [
|
||||
{
|
||||
content: 'Click on Start',
|
||||
trigger: 'button.btn:contains("Start")',
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 2")',
|
||||
}, {
|
||||
content: 'Check that Q4 and Q5 are visible',
|
||||
trigger: 'div.js_question-wrapper:contains(Q4)',
|
||||
extra_trigger: 'div.js_question-wrapper:contains(Q5)',
|
||||
run: () => {
|
||||
const selector = 'div.js_question-wrapper.d-none';
|
||||
if (document.querySelectorAll(selector).length !== 2) {
|
||||
throw new Error('Q2 and Q3 should be hidden.');
|
||||
}
|
||||
},
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 1")',
|
||||
}, {
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: 'div.js_question-wrapper:contains("Q4")',
|
||||
},
|
||||
{
|
||||
content: 'Answer Q2 with Answer 1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2") label:contains("Answer 1")',
|
||||
run: function (actions) {
|
||||
const selector = 'div.js_question-wrapper.d-none';
|
||||
if (document.querySelectorAll(selector).length !== 3) {
|
||||
throw new Error('Q3, Q4 and Q5 should be hidden.');
|
||||
}
|
||||
// Select Answer 1, in order to trigger the display of Q3.
|
||||
actions.click(this.$anchor);
|
||||
}
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q3 with Answer 1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3") label:contains("Answer 1")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 3', // This should hide all remaining questions.
|
||||
content: 'Answer Q1 with Answer 3', // This should hide Q2 and Q4 but not Q3.
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 3")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that Q2 was hidden',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3")',
|
||||
run : () => {
|
||||
expectHiddenQuestion("Q2");
|
||||
expectHiddenQuestion("Q4");
|
||||
},
|
||||
}, {
|
||||
content: 'Answer Q3 with Answer 2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 2', // This should hide all other questions.
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that only question 1 is now visible',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1")',
|
||||
run: () => {
|
||||
const selector = 'div.js_question-wrapper.d-none';
|
||||
if (document.querySelectorAll(selector).length !== 4) {
|
||||
throw new Error('Q2, Q3, Q4 and Q5 should have been hidden.');
|
||||
}
|
||||
}
|
||||
run : () => {
|
||||
expectHiddenQuestion("Q2", "Q2's trigger is gone.");
|
||||
expectHiddenQuestion("Q3", "No reason to show it now.");
|
||||
expectHiddenQuestion("Q4", "No reason to show it now.");
|
||||
},
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 3', // This shows Q3.
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 3")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that questions Q2 and Q4 are hidden',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1")',
|
||||
run : () => {
|
||||
expectHiddenQuestion("Q2", "Q2 should stay hidden.");
|
||||
expectHiddenQuestion("Q4", "Q4 should stay hidden.");
|
||||
},
|
||||
}, {
|
||||
content: 'Answer Q3 with Answer 2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that only question 1 is now the only one visible again',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1")',
|
||||
run : () => {
|
||||
expectHiddenQuestion("Q2", "Q2's trigger is gone, again.");
|
||||
expectHiddenQuestion("Q3", "As Q2's gone, so should this one.");
|
||||
expectHiddenQuestion("Q4", "No reason to show it now.");
|
||||
},
|
||||
}, {
|
||||
content: 'Click Submit and finish the survey',
|
||||
trigger: 'button[value="finish"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Click on Submit",
|
||||
trigger: 'button.btn-primary:contains("Submit")',
|
||||
run: "click",
|
||||
},
|
||||
// Final page
|
||||
{
|
||||
|
|
@ -62,6 +92,12 @@ tour.register('test_survey_chained_conditional_questions', {
|
|||
trigger: 'h1:contains("Thank you!")',
|
||||
}
|
||||
|
||||
]);
|
||||
]});
|
||||
|
||||
});
|
||||
export function expectHiddenQuestion(questionTitle, msg) {
|
||||
const divs = document.querySelectorAll("div.js_question-wrapper.d-none");
|
||||
const matchingDivs = Array.from(divs).filter((div) => div.textContent.includes(questionTitle));
|
||||
if (matchingDivs.length !== 1) {
|
||||
console.error(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
import { registry } from "@web/core/registry";
|
||||
import { expectHiddenQuestion } from "@survey/../tests/tours/survey_chained_conditional_questions";
|
||||
|
||||
registry.category("web_tour.tours").add('test_survey_conditional_question_on_different_page', {
|
||||
url: '/survey/start/1cb935bd-2399-4ed1-9e10-c649318fb4dc',
|
||||
steps: () => [
|
||||
{
|
||||
content: 'Click on Start',
|
||||
trigger: 'button.btn:contains("Start")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 1")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Go to next page',
|
||||
trigger: 'button[value="next"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that Q3 is visible',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3")',
|
||||
}, {
|
||||
content: 'Answer Q2 with Answer 2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that Q3 is still visible',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3")',
|
||||
}, {
|
||||
content: 'Go back',
|
||||
trigger: 'button[value="previous"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q1 with Answer 2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Go to next page',
|
||||
trigger: 'button[value="next"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that Q3 is hidden',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2")',
|
||||
run : () => expectHiddenQuestion("Q3", "Q3 should be hidden as q1_a1 trigger is not selected anymore"),
|
||||
}, {
|
||||
content: 'Answer Q2 with Answer 1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2") label:contains("Answer 1")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check that Q3 is now visible again',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3")',
|
||||
}
|
||||
],
|
||||
});
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
import { registry } from "@web/core/registry";
|
||||
import { stepUtils } from "@web_tour/tour_utils";
|
||||
|
||||
registry.category("web_tour.tours").add('survey_tour_test_survey_form_triggers', {
|
||||
url: '/odoo',
|
||||
steps: () => [
|
||||
stepUtils.showAppsMenuItem(),
|
||||
{
|
||||
content: 'Go to Survey',
|
||||
trigger: '.o_app[data-menu-xmlid="survey.menu_surveys"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Create a new survey",
|
||||
trigger: ".o-kanban-button-new",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Set the Survey's title",
|
||||
trigger: ".o_field_widget[name=title] textarea",
|
||||
run: "edit Test survey",
|
||||
}, {
|
||||
content: "Add a first question",
|
||||
trigger: "td.o_field_x2many_list_row_add a",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Set the first question's title",
|
||||
trigger: ".modal .modal-content .o_field_widget[name=title] input",
|
||||
run: "edit Question 1",
|
||||
},
|
||||
...addTwoAnswers(),
|
||||
...saveAndNew(),
|
||||
{
|
||||
content: "Set the second question's title",
|
||||
trigger: ".modal .o_field_widget[name=title] input",
|
||||
run: "edit Question 2",
|
||||
},
|
||||
...addTwoAnswers(),
|
||||
...changeTab("options"),
|
||||
{
|
||||
content: "Set a trigger for the first question",
|
||||
trigger: ".modal .o_field_widget[name=triggering_answer_ids] input",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Set the first question's first answer as trigger",
|
||||
trigger: ".modal ul.ui-autocomplete a:contains(Question 1 : Answer A)",
|
||||
run: 'click',
|
||||
},
|
||||
...changeTab("answers"),
|
||||
...saveAndNew(),
|
||||
{
|
||||
content: "Set the third question's title",
|
||||
trigger: ".modal .o_field_widget[name=title] input",
|
||||
run: "edit Question 3",
|
||||
},
|
||||
...addTwoAnswers(),
|
||||
...changeTab("options"),
|
||||
{
|
||||
content: "Set a trigger for the second question",
|
||||
trigger: ".modal .o_field_widget[name=triggering_answer_ids] input",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Set the second question's second answer as trigger",
|
||||
trigger: ".modal ul.ui-autocomplete a:contains(Question 2 : Answer B)",
|
||||
run: 'click',
|
||||
},
|
||||
{
|
||||
trigger: ".modal button:contains(save & close)",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: "body:not(:has(.modal))",
|
||||
},
|
||||
{
|
||||
content: "Check that Question 2 has 'normal' trigger icon",
|
||||
trigger: "tr:contains('Question 2') button i.fa-code-fork",
|
||||
}, {
|
||||
content: "Check that Question 3 has 'normal' trigger icon",
|
||||
trigger: "tr:contains('Question 3') button i.fa-code-fork",
|
||||
}, {
|
||||
content: "Move Question 3 above its trigger (Question 2)",
|
||||
trigger: "div[name=question_and_page_ids] table tr:eq(3) div[name=sequence]",
|
||||
run: "drag_and_drop(div[name=question_and_page_ids] table tr:eq(2))",
|
||||
}, {
|
||||
content: "Check that Question 3 has 'warning' trigger icon",
|
||||
trigger: "tr:contains('Question 3') button i.fa-exclamation-triangle",
|
||||
}, {
|
||||
content: "Open that question to check the server's misplacement evaluation agrees",
|
||||
trigger: "tr.o_data_row td:contains('Question 3')",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Check that an alert is shown",
|
||||
trigger: ".modal .o_form_sheet_bg div:first-child.alert-warning:contains('positioned before some or all of its triggers')",
|
||||
},
|
||||
...changeTab("options"),
|
||||
{
|
||||
content: "Remove invalid trigger",
|
||||
trigger: ".modal .o_field_widget[name=triggering_answer_ids] span:contains('Question 2') a.o_delete",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Check that the alert is gone",
|
||||
trigger: `.modal .o_form_sheet_bg div:first-child:not(.alert-warning).o_form_sheet`,
|
||||
}, {
|
||||
content: "Choose a new valid trigger",
|
||||
trigger: ".modal .o_field_widget[name=triggering_answer_ids] input",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Set the first question's second answer as trigger, then",
|
||||
trigger: 'ul.ui-autocomplete a:contains("Question 1 : Answer B")',
|
||||
run: 'click',
|
||||
},
|
||||
{
|
||||
content: "Save the question (1)",
|
||||
trigger: ".modal button:contains(save)",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: "body:not(:has(.modal))",
|
||||
},
|
||||
{
|
||||
content: "Check that Question 3 has its 'normal' trigger icon back",
|
||||
trigger: "tr:contains('Question 3') button i.fa-code-fork",
|
||||
}, {
|
||||
content: "Move Question 3 back below Question 2",
|
||||
trigger: "div[name=question_and_page_ids] table tr:eq(2) div[name=sequence]",
|
||||
run: "drag_and_drop(div[name=question_and_page_ids] table tr:eq(4))",
|
||||
}, {
|
||||
content: "Open that question again",
|
||||
trigger: "tr.o_data_row td:contains('Question 3')",
|
||||
run: "click",
|
||||
},
|
||||
...changeTab("options"),
|
||||
{
|
||||
trigger: ".modal .modal-content .o_field_widget[name=triggering_answer_ids] input",
|
||||
run() {
|
||||
this.anchor.scrollIntoView(true);
|
||||
}
|
||||
},
|
||||
{
|
||||
content: "Add a second trigger to confirm we can now use Question 2 again",
|
||||
trigger: ".modal .modal-content .o_field_widget[name=triggering_answer_ids] input",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Add the second question's second answer as trigger, then",
|
||||
trigger: '.modal-content ul.ui-autocomplete a:contains("Question 2 : Answer B")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Save the question (2)",
|
||||
trigger: ".modal button:contains(save)",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: "body:not(:has(.modal))",
|
||||
},
|
||||
// Move question 1 below question 3,
|
||||
{
|
||||
content: "Move Question 1 back below Question 3",
|
||||
trigger: "div[name=question_and_page_ids] table tr:eq(1) div[name=sequence]",
|
||||
run: "drag_and_drop(div[name=question_and_page_ids] table tr:eq(4))",
|
||||
}, {
|
||||
content: "Check that Question 3 has 'warning' trigger icon",
|
||||
trigger: "tr:contains('Question 3') button i.fa-exclamation-triangle",
|
||||
}, {
|
||||
content: "Open that question again",
|
||||
trigger: "tr.o_data_row td:contains('Question 3')",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Check that an alert is shown also when only one trigger is misplaced",
|
||||
trigger: ".modal .o_form_sheet_bg div:first-child.alert-warning:contains('positioned before some or all of its triggers')",
|
||||
},
|
||||
...changeTab("options"),
|
||||
{
|
||||
content: "Remove temporarily used trigger",
|
||||
trigger: ".modal .o_field_widget[name=triggering_answer_ids] span:contains('Question 1') a.o_delete",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Check that the alert is gone in this case too",
|
||||
trigger: `.modal .o_form_sheet_bg div:first-child:not(.alert-warning).o_form_sheet`,
|
||||
},
|
||||
{
|
||||
content: "Save the question (3)",
|
||||
trigger: ".modal button:contains(save)",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: "body:not(:has(.modal))",
|
||||
},
|
||||
{
|
||||
content: "Check that Question 3 has its 'normal' trigger icon back",
|
||||
trigger: "tr:contains('Question 3') button i.fa-code-fork",
|
||||
}, {
|
||||
content: "Move Question 1 back above Question 2",
|
||||
trigger: "div[name=question_and_page_ids] table tr:eq(3) div[name=sequence]",
|
||||
run: "drag_and_drop(div[name=question_and_page_ids] table tr:eq(1))",
|
||||
},
|
||||
// Deleting trigger answers or whole question gracefully remove the trigger automatically
|
||||
{
|
||||
content: "Open Question 2 again",
|
||||
trigger: "tr.o_data_row td:contains('Question 2')",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Delete Answer B",
|
||||
trigger: "div[name=suggested_answer_ids] tr:contains('Answer B') button[name=delete]",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Save the question (4)",
|
||||
trigger: ".modal button:contains(save)",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: "body:not(:has(.modal))",
|
||||
},
|
||||
{
|
||||
content: "Check that Question 3 no longer has a trigger icon",
|
||||
trigger: "div[name=question_and_page_ids] tr:contains('Question 3') div.o_widget_survey_question_trigger:not(:has(button)):not(:visible)",
|
||||
}, {
|
||||
content: "Check that Question 2 however still has a trigger icon",
|
||||
trigger: "tr:contains('Question 2') button i.fa-code-fork",
|
||||
}, {
|
||||
content: "Delete Question 1",
|
||||
trigger: "tr:contains('Question 1') button[name=delete]",
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Check that now Question 2 too does no longer have a trigger icon",
|
||||
trigger: "tr:contains('Question 2') div.o_widget_survey_question_trigger:not(:has(button)):not(:visible)",
|
||||
}, {
|
||||
content: 'Go back to Kanban View',
|
||||
trigger: '[data-menu-xmlid="survey.menu_survey_form"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Check that we arrived on the kanban view",
|
||||
trigger: ".o-kanban-button-new",
|
||||
}
|
||||
]});
|
||||
|
||||
function addTwoAnswers() {
|
||||
return [
|
||||
{
|
||||
content: "Add the first answer",
|
||||
trigger:
|
||||
".modal div[name=suggested_answer_ids] .o_field_x2many_list_row_add a",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: ".modal tr.o_selected_row div[name=value] input",
|
||||
run: "edit Answer A",
|
||||
},
|
||||
{
|
||||
content: "Add the second answer",
|
||||
trigger:
|
||||
".modal div[name=suggested_answer_ids] .o_field_x2many_list_row_add a",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
".modal tr:nth-child(2).o_selected_row div[name=value] input",
|
||||
run: "edit Answer B",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function saveAndNew() {
|
||||
return [
|
||||
{
|
||||
content: "Click Save & New",
|
||||
trigger: ".modal button.o_form_button_save_new",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Wait for the dialog to render new question form",
|
||||
trigger:
|
||||
".modal div[name=suggested_answer_ids] .o_list_table tbody tr:first-child:not(.o_data_row)", // empty answers list
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function changeTab(tabName) {
|
||||
return [
|
||||
{
|
||||
content: `Go to ${tabName} tab`,
|
||||
trigger: `.modal .modal-content a[name=${tabName}].nav-link`,
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: `Wait for tab ${tabName} tab`,
|
||||
trigger: `.modal .modal-content a[name=${tabName}].nav-link.active`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -1,155 +1,128 @@
|
|||
odoo.define('survey.tour_test_survey_prefill', function (require) {
|
||||
'use strict';
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
|
||||
tour.register('test_survey_prefill', {
|
||||
test: true,
|
||||
url: '/survey/start/b137640d-14d4-4748-9ef6-344caaaaaae'
|
||||
},
|
||||
[{ // Page-1
|
||||
registry.category("web_tour.tours").add('test_survey_prefill', {
|
||||
url: '/survey/start/b137640d-14d4-4748-9ef6-344caaaaaae',
|
||||
steps: () => [{ // Page-1
|
||||
trigger: 'button.btn.btn-primary.btn-lg:contains("Start Survey")',
|
||||
}, { // Question: Where do you live ?
|
||||
trigger: 'div.js_question-wrapper:contains("Where do you live ?") input',
|
||||
run: 'text Grand-Rosiere',
|
||||
}, { // Question: When is your date of birth ?
|
||||
trigger: 'div.js_question-wrapper:contains("When is your date of birth ?") input',
|
||||
run: 'text 05/05/1980',
|
||||
}, { // Question: How frequently do you buy products online ?
|
||||
trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online ?") label:contains("Once a week")',
|
||||
}, { // Question: How many times did you order products on our website ?
|
||||
trigger: 'div.js_question-wrapper:contains("How many times did you order products on our website ?") input',
|
||||
run: 'text 42',
|
||||
run: "click",
|
||||
}, { // Question: Where do you live?
|
||||
trigger: 'div.js_question-wrapper:contains("Where do you live?") input',
|
||||
run: "edit Grand-Rosiere",
|
||||
}, { // Question: When is your date of birth?
|
||||
trigger: 'div.js_question-wrapper:contains("When is your date of birth?") input',
|
||||
run: "edit 05/05/1980",
|
||||
}, { // Question: How frequently do you buy products online?
|
||||
trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online?") label:contains("Once a week")',
|
||||
run: "click",
|
||||
}, { // Question: How many times did you order products on our website?
|
||||
trigger: 'div.js_question-wrapper:contains("How many times did you order products on our website?") input',
|
||||
run: "edit 42",
|
||||
}, {
|
||||
content: 'Click on Next Page',
|
||||
trigger: 'button[value="next"]',
|
||||
run: "click",
|
||||
},
|
||||
// Page-2
|
||||
{ // Question: Which of the following words would you use to describe our products ?
|
||||
{ // Question: Which of the following words would you use to describe our products?
|
||||
content: 'Answer Which of the following words would you use to describe our products (High Quality)',
|
||||
trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Which of the following words would you use to describe our products (Good value for money)',
|
||||
trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (The new layout and design is fresh and up-to-date)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") td:first',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (It is easy to find the product that I want)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") td:eq(2)',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (The tool to compare the products is useful to make a choice)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") td:eq(3)',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (The checkout process is clear and secure)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") td:eq(2)',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer What do your think about our new eCommerce (I have added products to my wishlist)',
|
||||
trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") td:last',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Do you have any other comments, questions, or concerns',
|
||||
trigger: 'div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea',
|
||||
run: 'text Is the prefill working?',
|
||||
run: "edit Is the prefill working?",
|
||||
}, {
|
||||
content: 'Answer How would you rate your experience on our website?',
|
||||
trigger: 'div.js_question-wrapper:contains("How would you rate your experience on our website") label:contains("4")',
|
||||
run: "click",
|
||||
}, {
|
||||
// Go back to previous page
|
||||
content: 'Click on the previous page name in the breadcrumb',
|
||||
trigger: 'ol.breadcrumb a:first',
|
||||
}, {
|
||||
trigger: 'div.js_question-wrapper:contains("How many times did you order products on our website ?") input',
|
||||
run: function () {
|
||||
var $inputQ3 = $('div.js_question-wrapper:contains("How many times did you order products on our website ?") input');
|
||||
if ($inputQ3.val() === '42.0') {
|
||||
$('.o_survey_title').addClass('prefilled');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
trigger: '.o_survey_title.prefilled',
|
||||
run: function () {
|
||||
// check that all the answers are prefilled in Page 1
|
||||
var $inputQ1 = $('div.js_question-wrapper:contains("Where do you live ?") input');
|
||||
if ($inputQ1.val() !== 'Grand-Rosiere') {
|
||||
return;
|
||||
}
|
||||
|
||||
var $inputQ2 = $('div.js_question-wrapper:contains("When is your date of birth ?") input');
|
||||
if ($inputQ2.val() !== '05/05/1980') {
|
||||
return;
|
||||
}
|
||||
|
||||
var $inputQ3 = $('div.js_question-wrapper:contains("How frequently do you buy products online ?") label:contains("Once a week") input');
|
||||
if (!$inputQ3.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $inputQ4 = $('div.js_question-wrapper:contains("How many times did you order products on our website ?") input');
|
||||
if ($inputQ4.val() !== '42.0') {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.o_survey_title').addClass('tour_success');
|
||||
}
|
||||
}, {
|
||||
trigger: '.o_survey_title.tour_success'
|
||||
}, {
|
||||
content: 'Click on Next Page',
|
||||
trigger: 'button[value="next"]',
|
||||
}, {
|
||||
trigger: 'div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea',
|
||||
run: function () {
|
||||
var $inputQ3 = $('div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea');
|
||||
if ($inputQ3.val() === "Is the prefill working?") {
|
||||
$('.o_survey_title').addClass('prefilled2');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
trigger: '.o_survey_title.prefilled2',
|
||||
run: function () {
|
||||
// check that all the answers are prefilled in Page 2
|
||||
var $input1Q1 = $('div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality") input');
|
||||
if (!$input1Q1.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $input2Q1 = $('div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money") input');
|
||||
if (!$input2Q1.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $input1Q2 = $('div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") input:first');
|
||||
if (!$input1Q2.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $input2Q2 = $('div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") input:eq(2)');
|
||||
if (!$input2Q2.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $input3Q2 = $('div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") input:eq(3)');
|
||||
if (!$input3Q2.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $input4Q2 = $('div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") input:eq(2)');
|
||||
if (!$input4Q2.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $input5Q2 = $('div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") input:last');
|
||||
if (!$input5Q2.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $inputQ3 = $('div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea');
|
||||
if ($inputQ3.val() !== "Is the prefill working?") {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.o_survey_title').addClass('tour_success_2');
|
||||
}
|
||||
}, {
|
||||
trigger: '.o_survey_title.tour_success_2'
|
||||
}
|
||||
]);
|
||||
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "check survey is prefilled",
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How many times did you order products on our website?") input:value(42)',
|
||||
},
|
||||
{
|
||||
trigger: `div.js_question-wrapper:contains("Where do you live?") input:value(Grand-Rosiere)`,
|
||||
},
|
||||
{
|
||||
trigger: `div.js_question-wrapper:contains("When is your date of birth?") input:value(05/05/1980)`,
|
||||
},
|
||||
{
|
||||
trigger: `div.js_question-wrapper:contains("How frequently do you buy products online?) label:contains("Once a week") input:hidden:checked`,
|
||||
},
|
||||
{
|
||||
trigger: ".o_survey_title",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Click on Next Page",
|
||||
trigger: 'button[value="next"]',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea:value(Is the prefill working?)',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality") input:hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money") input:hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") input:first:hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") input:eq(2):hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") input:eq(3):hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") input:eq(2):hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") input:last:hidden:checked',
|
||||
},
|
||||
{
|
||||
trigger:
|
||||
'div.js_question-wrapper:contains("How would you rate your experience on our website") label:contains("4") input:hidden:checked',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
import { registry } from '@web/core/registry';
|
||||
|
||||
registry.category('web_tour.tours').add('test_survey_roaming_mandatory_questions', {
|
||||
url: '/survey/start/853ebb30-40f2-43bf-a95a-bbf0e367a365',
|
||||
steps: () => [{
|
||||
content: 'Click on Start',
|
||||
trigger: 'button.btn:contains("Start")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Skip question Q1',
|
||||
trigger: 'button.btn:contains("Continue")',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: 'div.js_question-wrapper:contains("Q2")',
|
||||
},
|
||||
{
|
||||
content: 'Skip question Q2',
|
||||
trigger: 'button.btn:contains("Continue")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if Q3 button is Submit',
|
||||
trigger: 'button.btn:contains("Submit")',
|
||||
}, {
|
||||
content: 'Go back to Q2',
|
||||
trigger: 'button.btn[value="previous"]',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if the alert box is present',
|
||||
trigger: 'div.o_survey_question_error span',
|
||||
}, {
|
||||
content: 'Skip question Q2 again',
|
||||
trigger: 'button.btn:contains("Continue")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Answer Q3',
|
||||
trigger: 'div.js_question-wrapper:contains("Q3") label:contains("Answer 1")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Click on Submit',
|
||||
trigger: 'button.btn:contains("Submit")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Click on Submit",
|
||||
trigger: 'button.btn-primary:contains("Submit")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if question is Q1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1")',
|
||||
}, {
|
||||
content: 'Click on "Next Skipped" button',
|
||||
trigger: 'button.btn:contains("Next Skipped")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if question is Q2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2")',
|
||||
}, {
|
||||
content: 'Click on "Next Skipped" button',
|
||||
trigger: 'button.btn:contains("Next Skipped")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if question is Q1 again (should loop on skipped questions)',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1")',
|
||||
}, {
|
||||
content: 'Answer Q1',
|
||||
trigger: 'div.js_question-wrapper:contains("Q1") label:contains("Answer 2")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if the visible question is the skipped question Q2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2")',
|
||||
}, {
|
||||
content: 'Answer Q2',
|
||||
trigger: 'div.js_question-wrapper:contains("Q2") label:contains("Answer 3")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Click on Submit',
|
||||
trigger: 'button.btn:contains("Submit")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Click on Submit",
|
||||
trigger: 'button.btn-primary:contains("Submit")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Check if the survey is done',
|
||||
trigger: 'div.o_survey_finished h1:contains("Thank you!")',
|
||||
}],
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue