diff --git a/services/ui-src/src/containers/FAQ.test.js b/services/ui-src/src/containers/FAQ.test.js index ab5ffc78b..0d696bcfc 100644 --- a/services/ui-src/src/containers/FAQ.test.js +++ b/services/ui-src/src/containers/FAQ.test.js @@ -1,5 +1,6 @@ import React from "react"; import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import FAQ from "./FAQ"; it("has target _blank for the external link", () => { @@ -26,3 +27,19 @@ it("expands linked question", async () => { expect(btnEl).toHaveAttribute("aria-expanded", "true"); }); }); + +it("expand button opens all", async () => { + render(); + + const btnEl = await screen.findByRole("button", { + name: "Expand all to search with CTRL+F", + }); + const btnEl2 = await screen.findByRole("button", { + name: "What are the attachments for a 1915(b) Waiver - Request for Temporary Extension?", + }); + + userEvent.click(btnEl); + await waitFor(() => { + expect(btnEl2).toHaveAttribute("aria-expanded", "true"); + }); +}); diff --git a/services/ui-src/src/containers/FAQ.tsx b/services/ui-src/src/containers/FAQ.tsx index 0030de9f3..76fec7449 100644 --- a/services/ui-src/src/containers/FAQ.tsx +++ b/services/ui-src/src/containers/FAQ.tsx @@ -1,9 +1,13 @@ import React, { useEffect, useState } from "react"; import PageTitleBar from "../components/PageTitleBar"; import { helpDeskContact } from "../libs/helpDeskContact"; -import { FAQContent, oneMACFAQContent } from "../libs/faq/faqContent"; +import { + QuestionAnswer, + FAQContent, + oneMACFAQContent, +} from "../libs/faq/faqContent"; -import { Accordion, AccordionItem } from "@cmsgov/design-system"; +import { Accordion, AccordionItem, Button } from "@cmsgov/design-system"; import { MACCard } from "../components/MACCard"; /** Refactored out for later extraction by cms-ux-lib. However, using this @@ -37,8 +41,35 @@ export const FAQSection = ({ section }: { section: FAQContent }) => { }; const FAQ = () => { + const [faqItems, setFaqItems] = useState(oneMACFAQContent); const [hash, setHash] = useState(window.location.hash.replace("#", "")); + const toggleAccordianItem = (anchorText: string) => { + const newItems = faqItems.map((section) => { + return { + sectionTitle: section.sectionTitle, + qanda: section.qanda.map((qa) => { + const openState = + qa.anchorText === anchorText ? !qa.isOpen : qa.isOpen; + return { ...qa, isOpen: openState } as QuestionAnswer; + }), + } as FAQContent; + }); + setFaqItems(newItems); + }; + + const openAll = () => { + const newItems = faqItems.map((section) => { + return { + sectionTitle: section.sectionTitle, + qanda: section.qanda.map((qa) => { + return { ...qa, isOpen: true } as QuestionAnswer; + }), + } as FAQContent; + }); + setFaqItems(newItems); + }; + const hashHandler = () => { setHash((prev) => { const newHash = window.location.hash.replace("#", ""); @@ -97,7 +128,10 @@ const FAQ = () => {
- {oneMACFAQContent.map((section, idx) => ( + + {faqItems.map((section, idx) => ( /** To be replaced with {@link FAQSection} */

{section.sectionTitle}

@@ -109,6 +143,10 @@ const FAQ = () => { heading={questionAnswer.question} buttonClassName="accordion-button" contentClassName="accordion-content" + isControlledOpen={questionAnswer.isOpen} + onChange={() => + toggleAccordianItem(questionAnswer.anchorText) + } > {questionAnswer.answerJSX} diff --git a/services/ui-src/src/index.scss b/services/ui-src/src/index.scss index 9595429de..b0916c3bd 100644 --- a/services/ui-src/src/index.scss +++ b/services/ui-src/src/index.scss @@ -2946,3 +2946,8 @@ article.form-container { max-width: 540px; margin: 3rem 0; } + +.faqButtonLink { + @extend .ds-c-button; + margin: 10px; +} diff --git a/services/ui-src/src/libs/faq/faqContent.tsx b/services/ui-src/src/libs/faq/faqContent.tsx index 7513d3d96..d6afdb101 100644 --- a/services/ui-src/src/libs/faq/faqContent.tsx +++ b/services/ui-src/src/libs/faq/faqContent.tsx @@ -5,8 +5,9 @@ import { stateSystemOverviewTranscript } from "./stateSystemOverviewTranscript"; import { FILE_TYPES, FileTypesFAQListItem } from "../../utils/fileTypes"; import config from "../../utils/config"; -interface QuestionAnswer { +export interface QuestionAnswer { anchorText: string; + isOpen: boolean; question: string; answerJSX: JSX.Element; } @@ -25,6 +26,7 @@ export const oneMACFAQContent: FAQContent[] = [ qanda: [ { anchorText: "system", + isOpen: false, question: "Which system should I use for my state’s submission?", answerJSX: ( <> @@ -48,6 +50,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "browsers", + isOpen: false, question: "What browsers can I use to access the system?", answerJSX: (

@@ -58,6 +61,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "confirm-email", + isOpen: false, question: "What should we do if we don’t receive a confirmation email?", answerJSX: (

@@ -72,6 +76,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "is-official", + isOpen: false, question: "Is this considered the official state submission?", answerJSX: (

@@ -88,6 +93,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "onemac-roles", + isOpen: false, question: "What are the OneMAC user roles?", answerJSX: ( @@ -134,6 +140,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "acceptable-file-formats", + isOpen: false, question: "What are the kinds of file formats I can upload into OneMAC", answerJSX: (
@@ -157,6 +164,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "onboarding-materials", + isOpen: false, question: "Onboarding Materials", answerJSX: ( <> @@ -198,6 +206,7 @@ export const oneMACFAQContent: FAQContent[] = [ qanda: [ { anchorText: "spa-id-format", + isOpen: false, question: "What format is used to enter a SPA ID?", answerJSX: ( <> @@ -221,6 +230,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "medicaid-spa-attachments", + isOpen: false, question: "What are the attachments for a Medicaid SPA?", answerJSX: ( <> @@ -320,6 +330,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "medicaid-spa-rai-attachments", + isOpen: false, question: "What are the attachments for a Medicaid response to Request for Additional Information (RAI)?", answerJSX: ( @@ -354,6 +365,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "chip-spa-attachments", + isOpen: false, question: "What are the attachments for a CHIP SPA?", answerJSX: ( <> @@ -422,6 +434,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "chip-spa-rai-attachments", + isOpen: false, question: "What are the attachments for a CHIP SPA response to Request for Additional Information (RAI)?", answerJSX: ( @@ -486,6 +499,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "public-health-emergency", + isOpen: false, question: "Can I submit SPAs relating to the Public Health Emergency (PHE) in OneMAC?", answerJSX: ( @@ -502,6 +516,7 @@ export const oneMACFAQContent: FAQContent[] = [ qanda: [ { anchorText: "initial-waiver-id-format", + isOpen: false, question: "What format is used to enter a 1915(b) Initial Waiver number?", answerJSX: ( @@ -528,6 +543,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiver-renewal-id-format", + isOpen: false, question: "What format is used to enter a 1915(b) Waiver Renewal number?", answerJSX: ( @@ -554,6 +570,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiver-amendment-id-format", + isOpen: false, question: "What format is used to enter a 1915(b) Waiver Amendment number?", answerJSX: ( @@ -581,6 +598,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiver-id-help", + isOpen: false, question: "Who can I contact to help me figure out the correct 1915(b) Waiver Number?", answerJSX: ( @@ -595,6 +613,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiver-c-id", + isOpen: false, question: "What format is used to enter a 1915(c) waiver number?", answerJSX: ( <> @@ -624,6 +643,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiverb-attachments", + isOpen: false, question: "What attachments are needed to submit a 1915(b) waiver action?", answerJSX: ( @@ -707,6 +727,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiverb-rai-attachments", + isOpen: false, question: "What are the attachments for a 1915(b) Waiver response to Request for Additional Information (RAI)?", answerJSX: ( @@ -743,6 +764,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiver-extension-id-format", + isOpen: false, question: "What format is used to enter a 1915(b) and 1915(c) Temporary Extension number?", answerJSX: ( @@ -776,6 +798,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiver-extension-status", + isOpen: false, question: "Why does the status of my Temporary Extension Request continue to show as 'Submitted'?", answerJSX: ( @@ -791,6 +814,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiverb-extension-attachments", + isOpen: false, question: "What are the attachments for a 1915(b) Waiver - Request for Temporary Extension?", answerJSX: ( @@ -826,6 +850,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "waiverc-extension-attachments", + isOpen: false, question: "What are the attachments for a 1915(c) Waiver - Request for Temporary Extension", answerJSX: ( @@ -861,6 +886,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "appk", + isOpen: false, question: "Can I submit Appendix K amendments in OneMAC?", answerJSX: (

@@ -871,6 +897,7 @@ export const oneMACFAQContent: FAQContent[] = [ }, { anchorText: "appk-attachments", + isOpen: false, question: "What are the attachments for a 1915(c) Appendix K Waiver?", answerJSX: ( <> diff --git a/tests/cypress/cypress/e2e/FAQ_Page.spec.feature b/tests/cypress/cypress/e2e/FAQ_Page.spec.feature index 4e09f1903..1e6010784 100644 --- a/tests/cypress/cypress/e2e/FAQ_Page.spec.feature +++ b/tests/cypress/cypress/e2e/FAQ_Page.spec.feature @@ -127,3 +127,12 @@ Feature: OY2_Update_Text_on_FAQ_Page Then verify OneMAC State User Guide is valid Then verify OneMAC CMS User Guide link exists Then verify OneMAC CMS User Guide is valid + + + Scenario: Verify the Guides exist in the FAQ + Given I am on Login Page + When Clicking on FAQ Tab + Then verify the expand all button is visible + Then verify all sections are collapsed + Then click the expand all button + Then verify all sections are expanded \ No newline at end of file diff --git a/tests/cypress/cypress/e2e/common/steps.js b/tests/cypress/cypress/e2e/common/steps.js index 78c69156f..6e7dcccce 100644 --- a/tests/cypress/cypress/e2e/common/steps.js +++ b/tests/cypress/cypress/e2e/common/steps.js @@ -2500,3 +2500,15 @@ Then("verify the Withdrawal Requested caret button exists", () => { Then("expand the Withdrawal Requested caret", () => { OneMacPackageDetailsPage.expandWithdrawalRequestedCaretBtn(); }); +Then("verify the expand all button is visible", () => { + OneMacFAQPage.verifyExpandAllBtnExists(); +}); +Then("click the expand all button", () => { + OneMacFAQPage.clickExpandAllBtn(); +}); +Then("verify all sections are collapsed", () => { + OneMacFAQPage.verifyAllSectionsAreCollapsed(); +}); +Then("verify all sections are expanded", () => { + OneMacFAQPage.verifyAllSectionsAreExpanded(); +}); diff --git a/tests/cypress/support/pages/oneMacFAQPage.js b/tests/cypress/support/pages/oneMacFAQPage.js index 20af76b0b..ce511e4cc 100644 --- a/tests/cypress/support/pages/oneMacFAQPage.js +++ b/tests/cypress/support/pages/oneMacFAQPage.js @@ -92,6 +92,8 @@ const stateAdminGuideLink = "//div[@id='onboarding-materials']//a[text() = 'OneMAC State Administrator Guide']"; const cmsUserGuideLink = "//div[@id='onboarding-materials']//a[text() = 'OneMAC CMS User Guide']"; +const expandAllBtn = + "//button[contains(text(),'Expand all to search with CTRL+F')]"; export class oneMacFAQPage { verifyGeneralSectionExists() { @@ -368,5 +370,21 @@ export class oneMacFAQPage { verifyAttachmentsFor1915cRequestTempExtBody() { cy.get(attachmentsFor1915cRequestTempExtBody).should("be.visible"); } + verifyExpandAllBtnExists() { + cy.xpath(expandAllBtn).should("be.visible"); + } + clickExpandAllBtn() { + cy.xpath(expandAllBtn).click(); + } + verifyAllSectionsAreCollapsed() { + cy.get("button.accordion-button") + .should("have.attr", "aria-expanded", "false") + .and("have.length.greaterThan", 20); + } + verifyAllSectionsAreExpanded() { + cy.get("button.accordion-button") + .should("have.attr", "aria-expanded", "true") + .and("have.length.greaterThan", 20); + } } export default oneMacFAQPage;