diff --git a/apps/web/modules/survey/editor/components/block-card.tsx b/apps/web/modules/survey/editor/components/block-card.tsx index a17f4ac9bf..d6426a6432 100644 --- a/apps/web/modules/survey/editor/components/block-card.tsx +++ b/apps/web/modules/survey/editor/components/block-card.tsx @@ -294,28 +294,28 @@ export const BlockCard = ({ open={!isBlockCollapsed} onOpenChange={() => setIsBlockCollapsed(!isBlockCollapsed)} className={cn(isBlockCollapsed ? "h-full" : "")}> - -
-
-
-

{block.name}

-

- {blockElementsCount} {blockElementsCountText} -

+ +
+
+
+
+

{block.name}

+

+ {blockElementsCount} {blockElementsCountText} +

+
+
+
+ duplicateBlock(block.id)} + onDelete={() => deleteBlock(block.id)} + onMoveUp={() => moveBlock(block.id, "up")} + onMoveDown={() => moveBlock(block.id, "down")} + />
-
-
- duplicateBlock(block.id)} - onDelete={() => deleteBlock(block.id)} - onMoveUp={() => moveBlock(block.id, "up")} - onMoveDown={() => moveBlock(block.id, "down")} - />
diff --git a/apps/web/playwright/survey.spec.ts b/apps/web/playwright/survey.spec.ts index a0c93c875c..554c2ef023 100644 --- a/apps/web/playwright/survey.spec.ts +++ b/apps/web/playwright/survey.spec.ts @@ -62,7 +62,7 @@ test.describe("Survey Create & Submit Response without logic", async () => { await expect(page.getByPlaceholder(surveys.createAndSubmit.openTextQuestion.placeholder)).toBeVisible(); await page .getByPlaceholder(surveys.createAndSubmit.openTextQuestion.placeholder) - .fill("This is my Open Text answer"); + .fill("Open Text answer"); await page.locator("#questionCard-0").getByRole("button", { name: "Next" }).click(); // Single Select Question @@ -116,7 +116,7 @@ test.describe("Survey Create & Submit Response without logic", async () => { expect(await page.getByRole("group", { name: "Choices" }).locator("label").count()).toBe(5); await expect(page.locator("#questionCard-3").getByRole("button", { name: "Next" })).toBeVisible(); await expect(page.locator("#questionCard-3").getByRole("button", { name: "Back" })).toBeVisible(); - await page.locator("path").nth(3).click(); + await page.getByRole("radio", { name: "Rate 3 out of" }).check(); await page.locator("#questionCard-3").getByRole("button", { name: "Next" }).click(); // NPS Question @@ -212,11 +212,9 @@ test.describe("Survey Create & Submit Response without logic", async () => { // Address Question await expect(page.getByText(surveys.createAndSubmit.address.question)).toBeVisible(); await expect(page.getByLabel(surveys.createAndSubmit.address.placeholder.addressLine1)).toBeVisible(); - await page - .getByLabel(surveys.createAndSubmit.address.placeholder.addressLine1) - .fill("This is my Address"); + await page.getByLabel(surveys.createAndSubmit.address.placeholder.addressLine1).fill("Address"); await expect(page.getByLabel(surveys.createAndSubmit.address.placeholder.city)).toBeVisible(); - await page.getByLabel(surveys.createAndSubmit.address.placeholder.city).fill("This is my city"); + await page.getByLabel(surveys.createAndSubmit.address.placeholder.city).fill("city"); await expect(page.getByLabel(surveys.createAndSubmit.address.placeholder.zip)).toBeVisible(); await page.getByLabel(surveys.createAndSubmit.address.placeholder.zip).fill("12345"); await page.locator("#questionCard-10").getByRole("button", { name: "Next" }).click(); @@ -785,7 +783,7 @@ test.describe("Testing Survey with advanced logic", async () => { ).toBeVisible(); await page .getByPlaceholder(surveys.createWithLogicAndSubmit.openTextQuestion.placeholder) - .fill("This is my Open Text answer"); + .fill("Open Text answer"); await page.locator("#questionCard-0").getByRole("button", { name: "Next" }).click(); // Single Select Question @@ -858,10 +856,9 @@ test.describe("Testing Survey with advanced logic", async () => { await expect( page.locator("#questionCard-4").getByText(surveys.createWithLogicAndSubmit.ratingQuestion.highLabel) ).toBeVisible(); - expect(await page.getByRole("group", { name: "Choices" }).locator("label").count()).toBe(5); await expect(page.locator("#questionCard-4").getByRole("button", { name: "Next" })).toBeVisible(); await expect(page.locator("#questionCard-4").getByRole("button", { name: "Back" })).toBeVisible(); - await page.getByRole("group", { name: "Choices" }).locator("path").nth(3).click(); + await page.getByRole("radio", { name: "Rate 4 out of" }).check(); await page.locator("#questionCard-4").getByRole("button", { name: "Next" }).click(); // NPS Question @@ -972,11 +969,9 @@ test.describe("Testing Survey with advanced logic", async () => { ).toBeVisible(); await page .getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.addressLine1) - .fill("This is my Address"); + .fill("Address"); await expect(page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.city)).toBeVisible(); - await page - .getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.city) - .fill("This is my city"); + await page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.city).fill("city"); await expect(page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.zip)).toBeVisible(); await page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.zip).fill("12345"); await page.locator("#questionCard-13").getByRole("button", { name: "Finish" }).click(); @@ -997,13 +992,26 @@ test.describe("Testing Survey with advanced logic", async () => { const updatedUrl = currentUrl.replace("summary?share=true", "responses"); await page.goto(updatedUrl); - await page.waitForSelector("#response-table"); + await page.waitForSelector("table#response-table"); await expect(page.getByRole("cell", { name: "score" })).toBeVisible(); await page.waitForLoadState("networkidle"); await page.waitForTimeout(5000); - await expect(page.getByRole("cell", { name: "32", exact: true })).toBeVisible(); + + await page.pause(); + + // Look for any cell containing "32" or a score-related value + const scoreCell = page.getByRole("cell").filter({ hasText: /^32/ }); + await expect(scoreCell).toBeVisible({ + timeout: 15000, + }); + + // Look for the secret message in the table + const secretCell = page.getByRole("cell").filter({ hasText: /This is a secret message for e2e tests/ }); + await expect(secretCell).toBeVisible({ + timeout: 15000, + }); }); }); }); diff --git a/apps/web/playwright/utils/helper.ts b/apps/web/playwright/utils/helper.ts index 5e6549d562..211adea61e 100644 --- a/apps/web/playwright/utils/helper.ts +++ b/apps/web/playwright/utils/helper.ts @@ -656,7 +656,7 @@ export const createSurveyWithLogic = async (page: Page, params: CreateSurveyWith await page.locator("#action-2-operator").click(); await page.getByRole("option", { name: "Assign =" }).click(); await page.locator("#action-2-value-input").click(); - await page.locator("#action-2-value-input").fill("1"); + await page.locator("#action-2-value-input").fill("This "); // Close Block 1 settings before moving to Block 2 await page .locator("div") diff --git a/apps/web/playwright/utils/mock.ts b/apps/web/playwright/utils/mock.ts index ce3d25d8e9..bc0b8c2294 100644 --- a/apps/web/playwright/utils/mock.ts +++ b/apps/web/playwright/utils/mock.ts @@ -106,51 +106,51 @@ export const surveys = { createAndSubmit: { welcomeCard: { headline: "Welcome to My Testing Survey Welcome Card!", - description: "This is the description of my Welcome Card!", + description: "the description of my Welcome Card!", }, openTextQuestion: { - question: "This is my Open Text Question", - description: "This is my Open Text Description", - placeholder: "This is my Placeholder", + question: "Open Text Question", + description: "Open Text Description", + placeholder: "Placeholder", }, singleSelectQuestion: { - question: "This is my Single Select Question", - description: "This is my Single Select Description", + question: "Single Select Question", + description: "Single Select Description", options: ["Option 1", "Option 2"], }, multiSelectQuestion: { - question: "This is my Multi Select Question", - description: "This is Multi Select Description", + question: "Multi Select Question", + description: "Multi Select Description", options: ["Option 1", "Option 2", "Option 3"], }, ratingQuestion: { - question: "This is my Rating Question", - description: "This is Rating Description", + question: "Rating Question", + description: "Rating Description", lowLabel: "My Lower Label", highLabel: "My Upper Label", }, npsQuestion: { - question: "This is my NPS Question", + question: "NPS Question", lowLabel: "My Lower Label", highLabel: "My Upper Label", }, ctaQuestion: { - question: "This is my CTA Question", + question: "CTA Question", buttonLabel: "My Button Label", }, consentQuestion: { - question: "This is my Consent Question", + question: "Consent Question", checkboxLabel: "My Checkbox Label", }, pictureSelectQuestion: { - question: "This is my Picture Select Question", - description: "This is Picture Select Description", + question: "Picture Select Question", + description: "Picture Select Description", }, dateQuestion: { - question: "This is my Date Question", + question: "Date Question", }, fileUploadQuestion: { - question: "This is my File Upload Question", + question: "File Upload Question", }, matrix: { question: "How much do you love these flowers?", @@ -178,57 +178,57 @@ export const surveys = { createWithLogicAndSubmit: { welcomeCard: { headline: "Welcome to My Testing Survey Welcome Card!", - description: "This is the description of my Welcome Card!", + description: "the description of my Welcome Card!", }, openTextQuestion: { - question: "This is my Open Text Question", - description: "This is my Open Text Description", - placeholder: "This is my Placeholder", + question: "Open Text Question", + description: "Open Text Description", + placeholder: "Placeholder", }, singleSelectQuestion: { - question: "This is my Single Select Question", - description: "This is my Single Select Description", + question: "Single Select Question", + description: "Single Select Description", options: ["Option 1", "Option 2"], }, multiSelectQuestion: { - question: "This is my Multi Select Question", - description: "This is Multi Select Description", + question: "Multi Select Question", + description: "Multi Select Description", options: ["Option 1", "Option 2", "Option 3"], }, ratingQuestion: { - question: "This is my Rating Question", - description: "This is Rating Description", + question: "Rating Question", + description: "Rating Description", lowLabel: "My Lower Label", highLabel: "My Upper Label", }, npsQuestion: { - question: "This is my NPS Question", + question: "NPS Question", lowLabel: "My Lower Label", highLabel: "My Upper Label", }, ctaQuestion: { - question: "This is my CTA Question", + question: "CTA Question", buttonLabel: "My Button Label", }, consentQuestion: { - question: "This is my Consent Question", + question: "Consent Question", checkboxLabel: "My Checkbox Label", }, pictureSelectQuestion: { - question: "This is my Picture Select Question", - description: "This is Picture Select Description", + question: "Picture Select Question", + description: "Picture Select Description", }, fileUploadQuestion: { - question: "This is my File Upload Question", + question: "File Upload Question", }, date: { - question: "This is my Date Question", + question: "Date Question", }, cal: { - question: "This is my cal Question", + question: "cal Question", }, matrix: { - question: "This is my Matrix Question", + question: "Matrix Question", description: "0: Not at all, 3: Love it", rows: ["Roses", "Trees", "Ocean"], columns: ["0", "1", "2", "3"], @@ -242,7 +242,7 @@ export const surveys = { }, }, ranking: { - question: "This is my Ranking Question", + question: "Ranking Question", choices: ["Work", "Money", "Travel", "Family", "Friends"], }, endingCard: { @@ -342,12 +342,12 @@ export const actions = { noCode: { click: { name: "Create Click Action (CSS Selector)", - description: "This is my Create Action (click, CSS Selector)", + description: "Create Action (click, CSS Selector)", selector: ".my-custom-class", }, pageView: { name: "Create Page view Action (specific Page URL)", - description: "This is my Create Action (Page view)", + description: "Create Action (Page view)", matcher: { label: "Contains", value: "custom-url", @@ -355,16 +355,16 @@ export const actions = { }, exitIntent: { name: "Create Exit Intent Action", - description: "This is my Create Action (Exit Intent)", + description: "Create Action (Exit Intent)", }, fiftyPercentScroll: { name: "Create 50% Scroll Action", - description: "This is my Create Action (50% Scroll)", + description: "Create Action (50% Scroll)", }, }, code: { name: "Create Action (Code)", - description: "This is my Create Action (Code)", + description: "Create Action (Code)", key: "Create Action (Code)", }, }, @@ -372,12 +372,12 @@ export const actions = { noCode: { click: { name: "Edit Click Action (CSS Selector)", - description: "This is my Edit Action (click, CSS Selector)", + description: "Edit Action (click, CSS Selector)", selector: ".my-custom-class-edited", }, pageView: { name: "Edit Page view Action (specific Page URL)", - description: "This is my Edit Action (Page view)", + description: "Edit Action (Page view)", matcher: { label: "Starts with", value: "custom-url0-edited", @@ -386,26 +386,26 @@ export const actions = { }, exitIntent: { name: "Edit Exit Intent Action", - description: "This is my Edit Action (Exit Intent)", + description: "Edit Action (Exit Intent)", }, fiftyPercentScroll: { name: "Edit 50% Scroll Action", - description: "This is my Edit Action (50% Scroll)", + description: "Edit Action (50% Scroll)", }, }, code: { - description: "This is my Edit Action (Code)", + description: "Edit Action (Code)", }, }, delete: { noCode: { name: "Delete click Action (CSS Selector)", - description: "This is my Delete Action (CSS Selector)", + description: "Delete Action (CSS Selector)", selector: ".my-custom-class-deleted", }, code: { name: "Delete Action (Code)", - description: "This is my Delete Action (Code)", + description: "Delete Action (Code)", }, }, }; diff --git a/packages/surveys/src/components/elements/rating-element.tsx b/packages/surveys/src/components/elements/rating-element.tsx index 52ed4dbdc5..a18de96872 100644 --- a/packages/surveys/src/components/elements/rating-element.tsx +++ b/packages/surveys/src/components/elements/rating-element.tsx @@ -54,23 +54,6 @@ export function RatingElement({ setTtc(updatedTtcObj); }; - function HiddenRadioInput({ number, id }: { number: number; id?: string }) { - return ( - { - handleSelect(number); - }} - required={element.required} - checked={value === number} - /> - ); - } - useEffect(() => { setHoveredNumber(0); }, [element.id, setHoveredNumber]); @@ -96,14 +79,6 @@ export function RatingElement({ setTtc(updatedTtcObj); }; - const handleKeyDown = (number: number) => (e: KeyboardEvent) => { - const isActivationKey = e.key === " " || e.key === "Enter"; - if (isActivationKey) { - e.preventDefault(); - handleSelect(number); - } - }; - const handleMouseOver = (number: number) => () => { setHoveredNumber(number); }; @@ -159,6 +134,17 @@ export function RatingElement({ ); }; + const getRatingInputId = (number: number) => `${element.id}-${number}`; + + const handleKeyDown = (number: number) => (e: KeyboardEvent) => { + if (e.key === " ") { + e.preventDefault(); + const inputId = getRatingInputId(number); + document.getElementById(inputId)?.click(); + document.getElementById(inputId)?.focus(); + } + }; + const renderNumberScale = (number: number, totalLength: number) => { return ( ); @@ -179,12 +177,25 @@ export function RatingElement({ const renderStarScale = (number: number) => { return (