Add e2e test for detailed poll results
This commit is contained in:
parent
e55c9a1a5b
commit
ebbdf80cd0
2 changed files with 95 additions and 4 deletions
|
@ -6,11 +6,11 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
Please see LICENSE files in the repository root for full details.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { test, expect } from "../../element-web-test";
|
import type { Locator, Page } from "@playwright/test";
|
||||||
import { Bot } from "../../pages/bot";
|
|
||||||
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
||||||
import { Layout } from "../../../src/settings/enums/Layout";
|
import { Layout } from "../../../src/settings/enums/Layout";
|
||||||
import type { Locator, Page } from "@playwright/test";
|
import { expect, test } from "../../element-web-test";
|
||||||
|
import { Bot } from "../../pages/bot";
|
||||||
|
|
||||||
test.describe("Polls", () => {
|
test.describe("Polls", () => {
|
||||||
type CreatePollOptions = {
|
type CreatePollOptions = {
|
||||||
|
@ -59,6 +59,35 @@ test.describe("Polls", () => {
|
||||||
).toContainText(`${votes} vote`);
|
).toContainText(`${votes} vote`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getPollResultsDialog = (page: Page): Locator => {
|
||||||
|
return page.locator(".mx_PollResultsDialog");
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPollResultsDialogOption = (page: Page, optionText: string): Locator => {
|
||||||
|
return getPollResultsDialog(page)
|
||||||
|
.locator(".mx_AnswerEntry")
|
||||||
|
.filter({ hasText: optionText });
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectDetailedPollOptionVoteCount = async (
|
||||||
|
page: Page,
|
||||||
|
pollId: string,
|
||||||
|
optionText: string,
|
||||||
|
votes: number,
|
||||||
|
optLocator?: Locator,
|
||||||
|
): Promise<void> => {
|
||||||
|
await expect(
|
||||||
|
getPollResultsDialogOption(page, optionText)
|
||||||
|
.locator(".mx_AnswerEntry_Header")
|
||||||
|
.locator(".mx_AnswerEntry_Header_answerName"),
|
||||||
|
).toContainText(optionText);
|
||||||
|
await expect(
|
||||||
|
getPollResultsDialogOption(page, optionText)
|
||||||
|
.locator(".mx_AnswerEntry_Header")
|
||||||
|
.locator(".mx_AnswerEntry_Header_voteCount"),
|
||||||
|
).toContainText(`${votes} vote`);
|
||||||
|
};
|
||||||
|
|
||||||
const botVoteForOption = async (
|
const botVoteForOption = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
bot: Bot,
|
bot: Bot,
|
||||||
|
@ -219,6 +248,67 @@ test.describe("Polls", () => {
|
||||||
await expect(page.locator(".mx_ErrorDialog")).toBeAttached();
|
await expect(page.locator(".mx_ErrorDialog")).toBeAttached();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should allow to view detailed results after voting", async ({ page, app, bot, user }) => {
|
||||||
|
const roomId: string = await app.client.createRoom({});
|
||||||
|
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||||
|
await page.goto("/#/room/" + roomId);
|
||||||
|
// wait until Bob joined
|
||||||
|
await expect(page.getByText("BotBob joined the room")).toBeAttached();
|
||||||
|
|
||||||
|
const locator = await app.openMessageComposerOptions();
|
||||||
|
await locator.getByRole("menuitem", { name: "Poll" }).click();
|
||||||
|
|
||||||
|
// Disabled because flaky - see https://github.com/vector-im/element-web/issues/24688
|
||||||
|
//cy.get(".mx_CompoundDialog").percySnapshotElement("Polls Composer");
|
||||||
|
|
||||||
|
const pollParams = {
|
||||||
|
title: "Does the polls feature work?",
|
||||||
|
options: ["Yes", "No", "Maybe?"],
|
||||||
|
};
|
||||||
|
await createPoll(page, pollParams);
|
||||||
|
|
||||||
|
// Wait for message to send, get its ID and save as @pollId
|
||||||
|
const pollId = await page
|
||||||
|
.locator(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]")
|
||||||
|
.filter({ hasText: pollParams.title })
|
||||||
|
.getAttribute("data-scroll-tokens");
|
||||||
|
await expect(getPollTile(page, pollId)).toMatchScreenshot("Polls_Timeline_tile_no_votes.png", {
|
||||||
|
mask: [page.locator(".mx_MessageTimestamp")],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bot votes 'Maybe' in the poll
|
||||||
|
await botVoteForOption(page, bot, roomId, pollId, pollParams.options[2]);
|
||||||
|
|
||||||
|
// no votes shown until I vote, check bots vote has arrived
|
||||||
|
await expect(
|
||||||
|
page.locator(".mx_MPollBody_totalVotes").getByText("1 vote cast. Vote to see the results"),
|
||||||
|
).toBeAttached();
|
||||||
|
|
||||||
|
// vote 'Maybe'
|
||||||
|
await getPollOption(page, pollId, pollParams.options[2]).click();
|
||||||
|
// both me and bot have voted Maybe
|
||||||
|
await expectPollOptionVoteCount(page, pollId, pollParams.options[2], 2);
|
||||||
|
|
||||||
|
// click the 'vote to see results' message
|
||||||
|
await page.locator(".mx_MPollBody_totalVotes").getByText("Based on 2 votes. Click here to see full results").click();
|
||||||
|
|
||||||
|
// expect the detailed results to be shown
|
||||||
|
await expect(getPollResultsDialog(page)).toBeAttached();
|
||||||
|
|
||||||
|
// expect results to be correctly shown
|
||||||
|
await expectDetailedPollOptionVoteCount(page, pollId, pollParams.options[2], 2);
|
||||||
|
const voterEntries = getPollResultsDialogOption(page, pollParams.options[2]).locator(".mx_VoterEntry");
|
||||||
|
expect((await voterEntries.all()).length).toBe(2);
|
||||||
|
expect(voterEntries.filter({ hasText: bot.credentials.displayName })).not.toBeNull();
|
||||||
|
expect(voterEntries.filter({hasText: user.displayName})).not.toBeNull();
|
||||||
|
|
||||||
|
// close the dialog
|
||||||
|
await page.locator(".mx_Dialog").getByRole("button", { name: "Close" }).click();
|
||||||
|
|
||||||
|
// expect the dialog to be closed
|
||||||
|
await expect(getPollResultsDialog(page)).not.toBeAttached();
|
||||||
|
});
|
||||||
|
|
||||||
test("should be displayed correctly in thread panel", async ({ page, app, user, bot, homeserver }) => {
|
test("should be displayed correctly in thread panel", async ({ page, app, user, bot, homeserver }) => {
|
||||||
const botCharlie = new Bot(page, homeserver, { displayName: "BotCharlie" });
|
const botCharlie = new Bot(page, homeserver, { displayName: "BotCharlie" });
|
||||||
await botCharlie.prepareClient();
|
await botCharlie.prepareClient();
|
||||||
|
|
|
@ -27,6 +27,7 @@ export default function PollResultsDialog(props: IProps): JSX.Element {
|
||||||
<BaseDialog
|
<BaseDialog
|
||||||
title={props.pollEvent.question.text}
|
title={props.pollEvent.question.text}
|
||||||
onFinished={() => Modal.closeCurrentModal()}
|
onFinished={() => Modal.closeCurrentModal()}
|
||||||
|
className="mx_PollResultsDialog"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
props.pollEvent.answers.map((answer) => {
|
props.pollEvent.answers.map((answer) => {
|
||||||
|
@ -55,7 +56,7 @@ function AnswerEntry(props: {
|
||||||
<div key={answer.id} className="mx_AnswerEntry">
|
<div key={answer.id} className="mx_AnswerEntry">
|
||||||
<div className="mx_AnswerEntry_Header">
|
<div className="mx_AnswerEntry_Header">
|
||||||
<span className="mx_AnswerEntry_Header_answerName">{answer.text}</span>
|
<span className="mx_AnswerEntry_Header_answerName">{answer.text}</span>
|
||||||
<span>{_t("poll|result_dialog|count_of_votes", { count: votes.length })}</span>
|
<span className="mx_AnswerEntry_Header_voteCount">{_t("poll|result_dialog|count_of_votes", { count: votes.length })}</span>
|
||||||
</div>
|
</div>
|
||||||
{votes.length === 0 && <div>No one voted for this.</div>}
|
{votes.length === 0 && <div>No one voted for this.</div>}
|
||||||
{votes.map((vote) => {
|
{votes.map((vote) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue