-
Notifications
You must be signed in to change notification settings - Fork 0
[Chore] - Updated version of cypress to 14.5.4 and fixed broken cypress tests a… #921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ function Header() { | |
| }, [isAuthenticated]); | ||
|
|
||
| const handleLogout = async () => { | ||
| setShowMobileMenu(false); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this Header is just a temporary filler, but noticed that the mobile menu doesn't close when a user clicks on the "Logout" button in the mobile navigation. This was causing the "logout" cypress test to fail. |
||
| try { | ||
| const response = await fetch(`${process.env.NEXT_PUBLIC_SERVER_ENDPOINT}/apollo-signout`, { | ||
| method: "POST", | ||
|
|
@@ -308,6 +309,7 @@ function Header() { | |
| <li role="menuitem"> | ||
| <Button | ||
| className="react-aria-Button secondary" | ||
| data-testid="logoutButtonDesktop" | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added test ids for easier testing in cypress
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. interesting. I've never seen
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea it makes it easier to test specific components. |
||
| onPress={handleLogout} | ||
| > | ||
| {t("btnLogout")} | ||
|
|
@@ -580,6 +582,7 @@ function Header() { | |
| <li role="menuitem"> | ||
| <Button | ||
| className="react-aria-Button secondary" | ||
| data-testid="logoutButtonMobile" | ||
| onPress={handleLogout} | ||
| > | ||
| {t("btnLogout")} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
|
|
||
| import { useEffect, useRef, useState } from 'react'; | ||
| import type { Editor as TinyMCEEditorType } from 'tinymce'; | ||
| import { loadTinymceScript } from '@/utils/loadTinyMCE'; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved loading of tinymce to it's own separate util that is used only when TinyMCEEditor is used on a page. |
||
| import styles from './tinyMCEEditor.module.scss'; | ||
|
|
||
| // We need to reference "window.tinymce" but TypeScript doesn't know about it. | ||
|
|
@@ -24,14 +25,16 @@ interface TinyMCEEditorProps { | |
| helpText?: string; | ||
| } | ||
|
|
||
|
|
||
| const TinyMCEEditor = ({ content, setContent, onChange, error, id, labelId, helpText }: TinyMCEEditorProps) => { | ||
| const editorRef = useRef<TinyMCEEditorType | null>(null); // Update the type here | ||
| const elementId = id || 'tiny-editor'; | ||
| const [isEditorReady, setIsEditorReady] = useState(false); | ||
|
|
||
| useEffect(() => { | ||
| const initEditor = async () => { | ||
| // Ensure tinymce library is available | ||
| await loadTinymceScript(); | ||
|
|
||
| // Make sure previous instance is removed | ||
| window.tinymce.remove(`#${elementId}`); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,11 +4,22 @@ | |
| describe('Authentication flow tests', () => { | ||
| // Base configuration | ||
| const baseUrl = Cypress.env('BASE_URL') || 'http://localhost:3000'; | ||
| const email = Cypress.env('TEST_USER_EMAIL') || '[email protected]'; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed tests. This was mostly to see if I could get Cypress tests to work, because previously it stopped working when we updated NextJS version. Glad to see that we can still get cypress to work for the app. We might consider using this for integration tests. |
||
| const password = Cypress.env('TEST_USER_PASSWORD') || 'Password123$9'; | ||
|
|
||
| beforeEach(() => { | ||
| // Clear cookies and local storage before each test | ||
| cy.clearCookies(); | ||
| cy.clearLocalStorage(); | ||
|
|
||
| // Ignore React hydration mismatches so tests can proceed | ||
| cy.on('uncaught:exception', (err) => { | ||
| if (/Hydration failed/.test(err.message)) { | ||
| return false; | ||
| } | ||
| // let other errors fail the test | ||
| return undefined; | ||
| }); | ||
| }); | ||
|
|
||
| describe('Login functionality', () => { | ||
|
|
@@ -19,7 +30,7 @@ describe('Authentication flow tests', () => { | |
| // Step 1: Enter email | ||
| cy.get('[data-testid="emailInput"]') | ||
| .should('be.visible') | ||
| .type(Cypress.env('TEST_USER_EMAIL')); | ||
| .type(email); | ||
|
|
||
| cy.get('[data-testid="actionContinue"]') | ||
| .should('be.enabled') | ||
|
|
@@ -28,7 +39,7 @@ describe('Authentication flow tests', () => { | |
| // Step 2: Enter password | ||
| cy.get('[data-testid="passInput"]') | ||
| .should('be.visible') | ||
| .type(Cypress.env('TEST_USER_PASSWORD'), { log: false }); // hide password in logs | ||
| .type(password, { log: false }); // hide password in logs | ||
|
|
||
| cy.get('[data-testid="actionSubmit"]') | ||
| .should('be.enabled') | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,9 +4,26 @@ | |
|
|
||
| // Base configuration | ||
| const baseUrl = Cypress.env('BASE_URL') || 'http://localhost:3000'; | ||
| const email = Cypress.env('TEST_USER_EMAIL') || '[email protected]'; | ||
| const password = Cypress.env('TEST_USER_PASSWORD') || 'Password123$9'; | ||
|
|
||
| describe('Authentication flow tests', () => { | ||
|
|
||
| beforeEach(() => { | ||
| // Clear before each run and ignore React hydration errors if any | ||
| cy.clearCookies(); | ||
| cy.clearLocalStorage(); | ||
| cy.on('uncaught:exception', (err) => { | ||
| if (/Hydration failed/.test(err.message)) { | ||
| return false; | ||
| } | ||
| if (/Failed to execute 'removeChild'/.test(err.message)) { | ||
| return false; | ||
| } | ||
| return undefined; | ||
| }); | ||
| }); | ||
|
|
||
| describe('Logout functionality on desktop', () => { | ||
| beforeEach(() => { | ||
| cy.viewport(1280, 720); | ||
|
|
@@ -19,7 +36,7 @@ describe('Authentication flow tests', () => { | |
| // Step 1: Enter email | ||
| cy.get('[data-testid="emailInput"]') | ||
| .should('be.visible') | ||
| .type(Cypress.env('TEST_USER_EMAIL')); | ||
| .type(email); | ||
|
|
||
| cy.get('[data-testid="actionContinue"]') | ||
| .should('be.enabled') | ||
|
|
@@ -28,17 +45,15 @@ describe('Authentication flow tests', () => { | |
| // Step 2: Enter password | ||
| cy.get('[data-testid="passInput"]') | ||
| .should('be.visible') | ||
| .type(Cypress.env('TEST_USER_PASSWORD'), { log: false }); // hide password in logs | ||
| .type(password, { log: false }); // hide password in logs | ||
|
|
||
| cy.get('[data-testid="actionSubmit"]') | ||
| .should('be.enabled') | ||
| .click(); | ||
|
|
||
| //Go to home page | ||
| cy.visit(`${baseUrl}/en-US`); | ||
|
|
||
| // Click logout button | ||
| cy.get('[data-method="delete"]').click(); | ||
| // Wait for login cookies and redirect to complete | ||
| // Without relying on cookies or navigation, wait for logout button in Header | ||
| cy.get('[data-testid="logoutButtonDesktop"]', { timeout: 10000 }).should('be.visible').click(); | ||
|
|
||
| // Verify redirect to login page | ||
| cy.url().should('include', '/login'); | ||
|
|
@@ -59,7 +74,7 @@ describe('Authentication flow tests', () => { | |
| // Step 1: Enter email | ||
| cy.get('[data-testid="emailInput"]') | ||
| .should('be.visible') | ||
| .type(Cypress.env('TEST_USER_EMAIL')); | ||
| .type(email); | ||
|
|
||
| cy.get('[data-testid="actionContinue"]') | ||
| .should('be.enabled') | ||
|
|
@@ -68,20 +83,25 @@ describe('Authentication flow tests', () => { | |
| // Step 2: Enter password | ||
| cy.get('[data-testid="passInput"]') | ||
| .should('be.visible') | ||
| .type(Cypress.env('TEST_USER_PASSWORD'), { log: false }); // hide password in logs | ||
| .type(password, { log: false }); // hide password in logs | ||
|
|
||
| cy.get('[data-testid="actionSubmit"]') | ||
| .should('be.enabled') | ||
| .click(); | ||
|
|
||
| //Go to home page | ||
| cy.visit(`${baseUrl}/en-US`); | ||
|
|
||
| // Wait for login cookies and redirect to complete | ||
| // Open dropdown menu from hamburger icon | ||
| cy.get('#mobile-menu-open').click(); | ||
| // Ensure the mobile menu has finished its slide-in transition | ||
| cy.get('#mobile-navigation') | ||
| .should('be.visible') | ||
| .and('have.css', 'right', '0px'); | ||
|
|
||
| //Click logout button | ||
| cy.get('[data-method="mobile-delete"]').click(); | ||
| //Click logout button (mobile) without relying on cookies | ||
| cy.get('#mobile-navigation [data-testid="logoutButtonMobile"]', { timeout: 10000 }) | ||
| .scrollIntoView() | ||
| .should('be.visible') | ||
| .click(); | ||
|
|
||
| // Verify redirect to login page | ||
| cy.url().should('include', '/login'); | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,7 +72,7 @@ | |
| "@types/react-dom": "18.3.7", | ||
| "@types/sanitize-html": "2.16.0", | ||
| "brace-expansion": "2.0.2", | ||
| "cypress": "14.4.1", | ||
| "cypress": "14.5.4", | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was reminded about this update by |
||
| "dotenv": "16.5.0", | ||
| "eslint": "9.28.0", | ||
| "eslint-config-next": "15.3.3", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
|
|
||
| let tinymceLoadPromise: Promise<void> | null = null; | ||
|
|
||
| export function loadTinymceScript(): Promise<void> { | ||
| if (typeof window === 'undefined') return Promise.resolve(); | ||
| if (window.tinymce) return Promise.resolve(); | ||
| if (tinymceLoadPromise) return tinymceLoadPromise; | ||
|
|
||
| tinymceLoadPromise = new Promise((resolve, reject) => { //singleton pattern - subsequent calls in same page return the same promise | ||
| const existing = document.querySelector('script[src="/tinymce/tinymce.min.js"]') as HTMLScriptElement | null; | ||
|
|
||
| if (existing) { | ||
| // Check if already loaded | ||
| if (window.tinymce) { | ||
| resolve(); | ||
| return; | ||
| } | ||
| // Still loading | ||
| existing.addEventListener('load', () => resolve()); | ||
| existing.addEventListener('error', () => reject(new Error('Failed to load TinyMCE script'))); | ||
| return; | ||
| } | ||
|
|
||
| const script = document.createElement('script'); | ||
| script.src = '/tinymce/tinymce.min.js'; | ||
| script.referrerPolicy = 'origin'; | ||
| script.async = true; | ||
| script.addEventListener('load', () => resolve()); | ||
| script.addEventListener('error', () => reject(new Error('Failed to load TinyMCE script'))); | ||
| document.head.appendChild(script); | ||
| }); | ||
|
|
||
| return tinymceLoadPromise; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this from because even with the
beforeInteractivewhich loads it early in the page lifecycle, it was still loading on every page, and most pages don't use TinyMCEEditor.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch.