diff --git a/tests/e2e/spec/tonedear.e2e.spec.js b/tests/e2e/spec/tonedear.e2e.spec.js index 8b132ab1f..c423e76ba 100644 --- a/tests/e2e/spec/tonedear.e2e.spec.js +++ b/tests/e2e/spec/tonedear.e2e.spec.js @@ -120,13 +120,50 @@ function runTests (driver, modes) { await driver.sleep(2000); // Give time for content to load await driver.switchTo().frame('articleContent'); - const androidIosLink = await driver.wait(until.elementLocated(By.css('a[href="android-ios-ear-training-app"]')), 5000); - await androidIosLink.click(); - // Switch back to default content before handling dialogs or verifying content - await driver.switchTo().defaultContent(); + const maxRetries = 3; + let retryCount = 0; + let navigationSuccessful = false; - // Wait time + while (!navigationSuccessful && retryCount < maxRetries) { + try { + const androidIosLink = await driver.wait(until.elementLocated(By.css('a[href="android-ios-ear-training-app"]')), 5000); + await androidIosLink.click(); + // Switch back to default content to handle any alerts + await driver.switchTo().defaultContent(); + // Wait for any potential error dialogs + await driver.sleep(1000); + try { + const errorDialog = await driver.findElement(By.css('.modal[style*="display: block"]')); + if (errorDialog) { + const okayButton = await driver.findElement(By.css('button.btn-primary')); + await okayButton.click(); + await driver.sleep(1000); + } + } catch (e) { + // No error dialog found, continue + } + navigationSuccessful = true; + } catch (e) { + retryCount++; + console.log(`Navigation attempt ${retryCount} failed:`, e.message); + // If we failed, try to switch back to default content before retrying + try { + await driver.switchTo().defaultContent(); + } catch (frameError) { + // Ignore frame switching errors + } + await driver.sleep(1000); + // Switch back to iframe for next attempt + await driver.switchTo().frame('articleContent'); + } + } + + if (!navigationSuccessful) { + throw new Error('Failed to navigate to Android & iOS page after ' + maxRetries + ' attempts'); + } + + // Wait for final navigation to complete await driver.sleep(1000); }); @@ -155,154 +192,59 @@ function runTests (driver, modes) { assert.strictEqual(iosDataSnippet, expectedIosSnippet, 'iOS image data matches expected'); } else if (serviceWorkerAPI && mode === 'serviceworker') { try { - // Wait for any alerts and handle them - await driver.sleep(2000); - try { - const alert = await driver.findElement(By.css('.modal[style*="display: block"]')); - if (alert) { - const okButton = await driver.findElement(By.css('button.btn-primary')); - await okButton.click(); - } - } catch (e) { - // No alert present, continue - } + // ServiceWorker mode test for image loading + await driver.sleep(3000); - // First verify we're in the iframe - const iframe = await driver.wait( - until.elementLocated(By.id('articleContent')), - 10000, - 'Article content iframe not found' - ); + const swRegistration = await driver.executeScript('return navigator.serviceWorker.ready'); + assert.ok(swRegistration, 'Service Worker is registered'); - // Switch to iframe - await driver.switchTo().frame(iframe); + console.log('Current URL:', await driver.getCurrentUrl()); - // Click the Android & iOS App link in the top navigation - // Using a more specific XPath that looks for the link in the navigation area - const androidIosLink = await driver.wait( - until.elementLocated( - By.xpath("//nav//a[contains(text(), 'Android & iOS App')] | //div[contains(@class, 'nav')]//a[contains(text(), 'Android & iOS App')]") - ), - 10000, - 'Android & iOS App navigation link not found' - ); - // Log the link details before clicking - const linkText = await androidIosLink.getText(); - const linkHref = await androidIosLink.getAttribute('href'); - console.log('Found navigation link:', { text: linkText, href: linkHref }); - - // Click the link - await androidIosLink.click(); + // Switch to the iframe that contains the Android and iOS images + const iframe = await driver.findElement(By.id('articleContent')); + await driver.switchTo().frame(iframe); - // Switch back to default content to handle any alerts - await driver.switchTo().defaultContent(); + // Wait for images to be visible on the page inside the iframe + await driver.wait(async function () { + const images = await driver.findElements(By.css('img[alt="Get it on Google Play"], img[alt="Get the iOS app"]')); + if (images.length === 0) return false; - // Wait for any navigation alerts - await driver.sleep(1000); - try { - const navigationAlert = await driver.findElement(By.css('.modal[style*="display: block"]')); - if (navigationAlert) { - const okayButton = await driver.findElement(By.css('button.btn-primary')); - await okayButton.click(); - } - } catch (e) { - // No alert present, continue - } + // Check if all images are visible + const visibility = await Promise.all(images.map(async (img) => { + return await img.isDisplayed(); + })); + return visibility.every((isVisible) => isVisible); + }, 10000, 'No visible store images found after 30 seconds'); - // Log the current URL to verify navigation - const currentUrl = await driver.getCurrentUrl(); - console.log('Current URL after navigation:', currentUrl); + const androidImage = await driver.findElement(By.css('img[alt="Get it on Google Play"]')); + const iosImage = await driver.findElement(By.css('img[alt="Get the iOS app"]')); - // Wait longer for the page to load after navigation - await driver.sleep(3000); + // Wait for images to load and verify dimensions + await driver.wait(async function () { + const androidLoaded = await driver.executeScript('return arguments[0].complete && arguments[0].naturalWidth > 0 && arguments[0].naturalHeight > 0;', androidImage); + const iosLoaded = await driver.executeScript('return arguments[0].complete && arguments[0].naturalWidth > 0 && arguments[0].naturalHeight > 0;', iosImage); + return androidLoaded && iosLoaded; + }, 5000, 'Images did not load successfully'); - // Switch back to iframe - await driver.switchTo().frame(iframe); + const androidWidth = await driver.executeScript('return arguments[0].naturalWidth;', androidImage); + const androidHeight = await driver.executeScript('return arguments[0].naturalHeight;', androidImage); - // Verify we're on the Android & iOS page - await driver.wait(async function () { - try { - const pageContent = await driver.executeScript(` - return { - url: window.location.href, - content: document.body.textContent - } - `); - console.log('Current page info:', pageContent); - return pageContent.content.includes('Android') && pageContent.content.includes('iOS'); - } catch (e) { - console.log('Error checking page content:', e.message); - return false; - } - }, 10000, 'Not on Android & iOS page after navigation'); + const iosWidth = await driver.executeScript('return arguments[0].naturalWidth;', iosImage); + const iosHeight = await driver.executeScript('return arguments[0].naturalHeight;', iosImage); - // Now look for the store images - await driver.wait(async function () { - try { - // Look for both images and links related to app stores - const elements = await driver.findElements(By.css(` - img[src*="play"], - img[src*="appstore"], - img[alt*="Google Play"], - img[alt*="App Store"], - a[href*="play.google.com"], - a[href*="apps.apple.com"] - `)); - - // Log what we found - if (elements.length > 0) { - for (const el of elements) { - // const tagName = await el.getTagName(); - const attrs = await driver.executeScript(` - const el = arguments[0]; - return { - tagName: el.tagName, - src: el.src || '', - href: el.href || '', - alt: el.alt || '', - isVisible: !!el.offsetParent - } - `, el); - console.log('Found store element:', attrs); - } - return true; - } - console.log('Store elements not found yet...'); - return false; - } catch (e) { - console.log('Error checking for store elements:', e.message); - return false; - } - }, 15000, 'Store elements not found after navigation'); + assert.ok(androidWidth > 0 && androidHeight > 0, 'Android image has valid dimensions'); + assert.ok(iosWidth > 0 && iosHeight > 0, 'iOS image has valid dimensions'); - // Switch back to default content + // Switch back to the main content after finishing the checks await driver.switchTo().defaultContent(); } catch (err) { - console.error('Test failure:', { - message: err.message, - name: err.name - }); - - // Log iframe state - try { - const iframeState = await driver.executeScript(` - const iframe = document.getElementById('articleContent'); - return iframe ? { - src: iframe.src, - displayed: !!iframe.offsetParent, - contentWindow: !!iframe.contentWindow - } : 'iframe not found'; - `); - console.log('Iframe state:', iframeState); - } catch (e) { - console.log('Could not get iframe state:', e.message); - } - + // If we still can't find the images, log the page source to help debug + console.error('Failed to find store images:', err.message); throw err; } } - // Exit if every test has been run and passed + // exit if every test and mode is completed if (mode === modes[modes.length - 1]) { return driver.quit(); }