/* eslint-disable max-len */ /// // Base widget with STL // no-dd-sa:typescript-node-security/detected-jwt-token const widget1Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2OWUxMWYwZDRkMDc0MWMwMjE0OGM4NyJ9.5-TNhGgodbvzb2aF1SxkCeE4NkLDKwWoumrJ_hrnpvA'; // Agreed media widget // no-dd-sa:typescript-node-security/detected-jwt-token const widget2Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2OWUxYWQwZDRkMDc0MWMwMjE0YjI1MyJ9.GMIiz4j24XIe46HXpWsA_nlkk9r6kgYtFLDkgXebIOc'; // Exact Medias with minimum 2 products linked // no-dd-sa:typescript-node-security/detected-jwt-token const widget3Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2OWUxYzdjZDRkMDc0MWMwMjE0YjhmOSJ9.PyF6VHFPHemcAP_UjEqU_jQ5CntSns_6_vDGTWAK7y0'; // Similar Medias with minimum 2 products linked // no-dd-sa:typescript-node-security/detected-jwt-token const widget4Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2OWUyMGY2ZDRkMDc0MWMwMjE0YzM2ZSJ9.ub3jdkztjFcm5OP33j0SJ56ITxulZY21voWBz3kLVPk'; // Widget with english products // no-dd-sa:typescript-node-security/detected-jwt-token const widget5Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2YTdiMTFjNzBhYTYwMmVkOTAzYzJkNyJ9.Q6z-hkX2IisqoQGLcWjveMp3aEQzdrWCkzV3hRWRd-E'; // Widget with minimum content not reached // no-dd-sa:typescript-node-security/detected-jwt-token const widget6Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2YTdiM2QxNzBhYTYwMmVkOTAzY2ZkZSJ9.Oiy1UBWrwoeyRxDZeiOSMJ0WeQTi_4SmyTPSCbY4MNQ'; // Widget with maximum number of medias // no-dd-sa:typescript-node-security/detected-jwt-token const widget7Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2YWI5ZWEzNzBhYTYwMmVkOTA5YjVjOCJ9.SakzCdTppcu1Hpmv0-SsFpLq6a1PaP-KIRRTG9Dhec8'; // Widget with maximum 2 exact products and 2 similar products displayed // no-dd-sa:typescript-node-security/detected-jwt-token const widget8Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2YWI5ZjVkNzBhYTYwMmVkOTA5YjhlNiJ9.BqW1tuOtlBnb7jqSrHGdVA_INl-Amw9xkpOfB2_yuYo'; // Widget with 6 videos // no-dd-sa:typescript-node-security/detected-jwt-token const widget9Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2YmI2NTJjMzk3M2EyNDNiM2QwMDRkYSJ9.okQ1mdQsnSyyX3WKg8ka8bebOeRMHD2Azdla3YWPloc'; // Widget for carousel layout test const widget10Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY5ODlmNDEwMTI4NTQ2YjVhODk3NDA5YiJ9.ZG_XdF9q3cRGRit91qtT8cnyM9PEXhHein_hpr7pUc4'; const visitAndLoadWidget = (token: string) => { // Load the widget cy.visit('http://localhost:3000'); // Type the widget token cy.get('#apiKey').clear().type(token); // Click the load button cy.get('#load').click(); }; const checkWidgetMediaNb = (mediaCount: number) => { // Check if the widget is visible cy.get('#widget').should('be.visible'); cy.get('.adl-wdgt-layout-wall').should('be.visible'); // There must be 'mediaCount' medias in the widget cy.get('.adl-wdgt-layout-wall .adl-wdgt-item .adl-wdgt-thumbnail').should( 'have.length', mediaCount, ); }; const clickOnFirstMedia = (shouldDisplayProducts: boolean = false) => { // Click on the first media cy.get('.adl-wdgt-layout-wall .adl-wdgt-item').first().click(); // Check if the modal is visible cy.get('.adl-wdgt-postviewer').should('be.visible'); cy.get('.adl-wdgt-postviewer-content').should('be.visible'); if (shouldDisplayProducts) { cy.get('.adl-wdgt-postviewer-details').should('be.visible'); } }; const clickOnNbMedia = (position: number, shouldDisplayProducts: boolean = false) => { // Click on the indicated media (careful : index is the position) cy.get('.adl-wdgt-layout-wall .adl-wdgt-item').eq(position).click(); cy.get('.adl-wdgt-postviewer').should('be.visible'); cy.get('.adl-wdgt-postviewer-content').should('be.visible'); if (shouldDisplayProducts) { cy.get('.adl-wdgt-postviewer-details').should('be.visible'); } }; const closeModal = () => { // Use force:true because the SVG icon child can intercept Cypress's hit-test. cy.get('.adl-wdgt-postviewer-close').click({ force: true }); checkModalDoesNotExists(); }; const checkModalDoesNotExists = () => { cy.get('.adl-wdgt-postviewer').should('not.exist'); cy.get('.adl-wdgt-postviewer-content').should('not.exist'); cy.get('.adl-wdgt-postviewer-details').should('not.exist'); }; const checkProductDisplay = (shouldExist: boolean) => { if (shouldExist) { cy.get('.adl-wdgt-postviewer-details').should('exist'); } else { cy.get('.adl-wdgt-postviewer-details').should('not.exist'); } }; const checkShopTheLookAvailability = (shouldExist: boolean) => { if (shouldExist) { cy.get('.adl-wdgt-postviewer-details').contains('div', 'SHOP THE LOOK').should('exist'); } else { cy.get('.adl-wdgt-postviewer-details').contains('div', 'SHOP THE LOOK').should('not.exist'); } }; const checkMoreLikeThisAvailability = (shouldExist: boolean) => { if (shouldExist) { cy.get('.adl-wdgt-postviewer-details').contains('div', 'More like this').should('exist'); } else { cy.get('.adl-wdgt-postviewer-details').contains('div', 'More like this').should('not.exist'); } }; const checkProductAvailability = (productName: string, shouldExist: boolean) => { if (shouldExist) { cy.get('.adl-wdgt-postviewer-details').contains(productName).should('exist'); } else { cy.get('.adl-wdgt-postviewer-details').contains(productName).should('not.exist'); } }; const clickNextButton = () => { cy.get('.adl-wdgt-arrow-right').click(); }; const clickPreviousButton = () => { cy.get('.adl-wdgt-arrow-left').click(); }; const checkLocalization = (text:string) => { cy.contains(text).should('exist'); }; // Function to check the maximum number of medias const checkMaxMedias = (maxCount:number) => { cy.get('.adl-wdgt-layout-wall .adl-wdgt-item').should('have.length.lte', maxCount); }; /** checkProducts function : * Usage examples : * Min 3 products : checkProductCount(3); * Max 5 products : checkProductCount(null, 5); * 3 to 5 products : checkProductCount(3, 5); * Validate that there are products : checkProductCount(); * */ // check the existence/count of medias for exact products const checkExactProducts = (minCount: number | null, maxCount: number | null) => { cy.get('.adl-wdgt-postviewer-details').then(($container) => { if ($container) { const shopThisLookSection = $container.find(':contains("SHOP THE LOOK")'); if (shopThisLookSection.length > 0) { // Get the immediate next sibling div which contains the products cy.wrap(shopThisLookSection) .parent() .next('div') .find('.adl-wdgt-postviewer-details-product') .then(($products) => { const productCount = $products.length; if (minCount !== null) { expect(productCount).to.be.at.least(minCount); } if (maxCount !== null) { expect(productCount).to.be.at.most(maxCount); } }); } else if (minCount === null) { // "SHOP THIS LOOK" section not found cy.log( 'SUCCESS: "Shop The Look" section is missing, but no defined minimum of exact medias', ); } else { throw new Error( 'FAIL: "Shop The Look" section is missing and there is a minimum number of exact medias expected.', ); } } else { throw new Error('FAIL: Unable to find .adl-wdgt-postviewer-details container.'); } }); }; // check the existence/count of medias for similar products const checkSimilarProducts = (minCount: number | null, maxCount: number | null) => { cy.get('.adl-wdgt-postviewer-details').then(($container) => { if ($container) { const moreLikeThisSection = $container.find(':contains("More like this")'); if (moreLikeThisSection.length > 0) { // Get the immediate next sibling div which contains the products cy.wrap(moreLikeThisSection) .parent() .next('div') .find('.adl-wdgt-postviewer-details-product') .then(($products) => { const productCount = $products.length; if (minCount !== null) { expect(productCount).to.be.at.least(minCount); } if (maxCount !== null) { expect(productCount).to.be.at.most(maxCount); } }); } else if (minCount === null) { // "MORE LIKE THIS" section not found cy.log( 'SUCCESS: "More Like This" section is missing, but no defined minimum of exact medias', ); } else { throw new Error( 'FAIL: "More Like This" section is missing and there is a minimum number of exact medias expected.', ); } } else { throw new Error('FAIL: Unable to find .adl-wdgt-postviewer-details container.'); } }); }; const iterateAndCheckMedia = ( checkFunction: (minCount: number | null, maxCount: number | null) => void, minCount: number | null = null, maxCount: number | null = null, ) => { cy.get('.adl-wdgt-layout-wall .adl-wdgt-item') .its('length') .then((totalItems) => { if (!totalItems) { throw new Error('FAIL: No medias found to iterate over.'); } const visitMedia = (currentIndex: number) => { cy.get('body').then(($body) => { const hasDetails = $body.find('.adl-wdgt-postviewer-details').length > 0; if (!hasDetails) { throw new Error('FAIL: Expected .adl-wdgt-postviewer-details to exist.'); } checkFunction(minCount, maxCount); }); if (currentIndex >= totalItems - 1) { closeModal(); return; } clickNextButton(); cy.get('.adl-wdgt-postviewer') .should('be.visible'); cy.wait(300); cy.get('.adl-wdgt-postviewer-details', { timeout: 10000 }) .should('exist') .then(() => { visitMedia(currentIndex + 1); }); }; cy.get('.adl-wdgt-layout-wall .adl-wdgt-item').first().click(); cy.get('.adl-wdgt-postviewer').should('be.visible'); cy.get('.adl-wdgt-postviewer-content').should('be.visible'); cy.then(() => { visitMedia(0); }); }); }; function iterateAndPlayVideos() { cy.get('.adl-wdgt-layout-wall .adl-wdgt-item').each((media, index, list) => { cy.get('.adl-wdgt-postviewer').should('be.visible'); cy.get('.adl-wdgt-postviewer-content').should('be.visible'); // The duration bar only renders while the video is playing — its presence // confirms autoplay succeeded. cy.get('[role="progressbar"][aria-label="Video progress"]').should('exist'); // Wait up to 5s for the progress bar to appear (video may load slowly) cy.get('[role="progressbar"][aria-label="Video progress"]', { timeout: 5000 }) .should('exist'); cy.wait(2500); // After playing for a moment the video position must have advanced. cy.get('[role="progressbar"][aria-label="Video progress"]') .invoke('attr', 'aria-valuenow') .then((val) => expect(Number(val)).to.be.greaterThan(0)); if (index < list.length - 1) { clickNextButton(); } }); } describe('Widget', () => { it('Should load and display the widget', () => { visitAndLoadWidget(widget1Token); checkWidgetMediaNb(32); checkModalDoesNotExists(); }); it('Should display the modal when clicking on a media', () => { visitAndLoadWidget(widget1Token); checkModalDoesNotExists(); clickOnFirstMedia(true); checkShopTheLookAvailability(true); checkProductAvailability('Cookies', true); closeModal(); }); it('Should change media when clicking on the arrow buttons', () => { visitAndLoadWidget(widget1Token); clickOnNbMedia(1, true); checkMoreLikeThisAvailability(true); checkProductAvailability('MacBook Pro', true); clickNextButton(); checkMoreLikeThisAvailability(true); checkProductAvailability('Tote Bag Ice Cream', true); checkProductAvailability('Mug AdAlong', false); checkProductAvailability('Cookies', false); checkProductAvailability('Galette de Rois', false); checkProductAvailability('La Felicità', false); checkProductAvailability('MacBook Pro', false); clickPreviousButton(); checkMoreLikeThisAvailability(true); checkProductAvailability('Galette de Rois', true); checkProductAvailability('La Felicità', true); checkProductAvailability('MacBook Pro', true); checkProductAvailability('Mug AdAlong', false); checkProductAvailability('Tote Bag Ice Cream', false); }); it('Should display widget for agreed media only (AGREED)', () => { visitAndLoadWidget(widget2Token); checkWidgetMediaNb(28); clickOnFirstMedia(false); // 'Details' component should not exist, since the widget does not display linked products checkProductDisplay(false); }); it('Should display the products in English (LOCALIZATION)', () => { visitAndLoadWidget(widget5Token); checkWidgetMediaNb(8); clickOnNbMedia(4, true); checkLocalization('Product'); }); it('Should display and play videos (VIDEOS)', () => { visitAndLoadWidget(widget9Token); checkWidgetMediaNb(6); cy.get('.adl-wdgt-layout-wall .adl-wdgt-item').first().click(); iterateAndPlayVideos(); closeModal(); }); it('Should emit minContentNotReached event if minimum content is not met (NUMBER OF UGCS : MIN)', () => { visitAndLoadWidget(widget6Token); cy.on('minContentNotReached', () => { cy.wrap(true).should('be.true'); }); }); it('Should display maximum 12 medias (NUMBER OF UGCS : MAX)', () => { visitAndLoadWidget(widget7Token); checkMaxMedias(12); }); it('Should display medias with minimum 2 exact products linked in the "SHOP THE LOOK" section (UGC FILTERS : EXACT - MIN)', () => { visitAndLoadWidget(widget3Token); iterateAndCheckMedia(checkExactProducts, 2, null); }); it('Should display medias with minimum 2 similar products linked in the "MORE LIKE THIS" section (UGC FILTERS : SIMILAR - MIN)', () => { visitAndLoadWidget(widget4Token); iterateAndCheckMedia(checkSimilarProducts, 2, null); }); it('Should display maximum 2 products in the "SHOP THE LOOK" section (STL DISPLAY : EXACT - MAX)', () => { visitAndLoadWidget(widget8Token); iterateAndCheckMedia(checkExactProducts, null, 2); }); it('Should display maximum 2 products in the "MORE LIKE THIS" section (STL DISPLAY : SIMILAR - MAX)', () => { visitAndLoadWidget(widget8Token); iterateAndCheckMedia(checkSimilarProducts, null, 2); }); it('Should not show arrows in mobile mode (carousel)', () => { visitAndLoadWidget(widget10Token); cy.viewport('iphone-6'); cy.get('body').then($body => { const isCarousel = $body.find('.adl-wdgt-layout-carousel').length > 0; if (isCarousel) { cy.get('.adl-wdgt-arrow-left').should('not.exist'); cy.get('.adl-wdgt-arrow-right').should('not.exist'); } else { cy.log('Carousel layout not present, skipping arrow check.'); } }); }); });