Skip to content

Commit

Permalink
Testing 21
Browse files Browse the repository at this point in the history
  • Loading branch information
THEBOSS0369 committed Dec 30, 2024
1 parent b19198f commit 33cbd3c
Showing 1 changed file with 67 additions and 163 deletions.
230 changes: 67 additions & 163 deletions tests/e2e/spec/tonedear.e2e.spec.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
/**
* tonedear.e2e.spec.js : End-to-end tests
*/
import { By, until } from 'selenium-webdriver';
/* eslint-disable no-undef */
import { By, until, WebDriver } from 'selenium-webdriver';

Check notice on line 2 in tests/e2e/spec/tonedear.e2e.spec.js

View check run for this annotation

codefactor.io / CodeFactor

tests/e2e/spec/tonedear.e2e.spec.js#L2

'WebDriver' is defined but never used. (no-unused-vars)
import assert from 'assert';
import paths from '../paths.js';

const BROWSERSTACK = !!process.env.BROWSERSTACK_LOCAL_IDENTIFIER;
const port = BROWSERSTACK ? '8099' : '8080';
const tonedearBaseFile = BROWSERSTACK ? '/tests/zims/tonedear/tonedear.com_en_2024-09.zim' : paths.tonedearBaseFile;

// Set the archive to load
let tonedearBaseFile = paths.tonedearBaseFile;
if (BROWSERSTACK) {
tonedearBaseFile = '/tests/zims/tonedear/tonedear.com_en_2024-09.zim';
}

/* global describe, it */
/**
* Run the tests
* @param {WebDriver} driver Selenium WebDriver object
* @param {array} modes Array of modes to run the tests in ['jquery', 'serviceworker']
* @param {Array} modes Array of modes to run the tests in
* @returns {Promise<void>} A Promise for the completion of the tests
*/
function runTests (driver, modes) {
// Set default modes if not provided
if (!modes) {
modes = ['jquery', 'serviceworker'];
}

let browserName, browserVersion;
driver.getCapabilities().then(function (caps) {
browserName = caps.get('browserName');
browserVersion = caps.get('browserVersion');
console.log('\nRunning Tonedear tests on: ' + browserName + ' ' + browserVersion);
});

// Set implicit wait timeout
// Set the implicit wait to 3 seconds
driver.manage().setTimeouts({ implicit: 3000 });

// Run in both jquery and serviceworker modes by default
if (!modes) {
modes = ['jquery', 'serviceworker'];
}

modes.forEach(function (mode) {
let serviceWorkerAPI = true;

// eslint-disable-next-line no-undef
describe('Tonedear Test Suite ' + (mode === 'jquery' ? '[JQuery mode]' : '[SW mode]'), function () {
describe('Tonedear test ' + (mode === 'jquery' ? '[JQuery mode]' : '[SW mode]'), function () {
this.timeout(60000);
this.slow(10000);

it('Load Kiwix JS and verify title', async function () {
it('Load Kiwix JS and check title', async function () {
await driver.get('http://localhost:' + port + '/dist/www/index.html?noPrompts=true');
await driver.sleep(1300);
await driver.navigate().refresh();
Expand All @@ -54,178 +45,91 @@ function runTests (driver, modes) {
});

it('Switch to ' + mode + ' mode', async function () {
const modeSelector = await driver.wait(
until.elementLocated(By.id(mode + 'ModeRadio'))
);
await driver.executeScript(
'var el=arguments[0]; el.scrollIntoView(true); setTimeout(function() {el.click();}, 50); return el.offsetParent;',
modeSelector
);
const modeSelector = await driver.wait(until.elementLocated(By.id(mode + 'ModeRadio')));
await driver.wait(async function () {
const elementIsVisible = await driver.executeScript(
'var el=arguments[0]; el.scrollIntoView(true); setTimeout(function () {el.click();}, 50); return el.offsetParent;',
modeSelector
);
return elementIsVisible;
}, 5000);
await driver.sleep(1300);

try {
const activeAlertModal = await driver.findElement(
By.css('.modal[style*="display: block"]')
);
const activeAlertModal = await driver.findElement(By.css('.modal[style*="display: block"]'));
if (activeAlertModal) {
serviceWorkerAPI = await driver.findElement(By.id('modalLabel'))
.getText()
.then(function (alertText) {
return !/ServiceWorker\sAPI\snot\savailable/i.test(alertText);
});
const approveButton = await driver.wait(
until.elementLocated(By.id('approveConfirm'))
);
serviceWorkerAPI = await driver.findElement(By.id('modalLabel')).getText().then(function (alertText) {
return !/ServiceWorker\sAPI\snot\savailable/i.test(alertText);
});
const approveButton = await driver.wait(until.elementLocated(By.id('approveConfirm')));
await approveButton.click();
}
} catch (e) {
// Do nothing
}

if (mode === 'serviceworker' && !serviceWorkerAPI) {
console.log('\x1b[33m%s\x1b[0m', ' Skipping SW mode tests because browser does not support API');
await driver.quit();
return;
}

// Disable source verification in SW mode
if (mode === 'serviceworker') {
// Disable source verification in SW mode as the dialogue box gave inconsistent test results
const sourceVerificationCheckbox = await driver.findElement(By.id('enableSourceVerification'));
if (sourceVerificationCheckbox.isSelected()) {
if (await sourceVerificationCheckbox.isSelected()) {
await sourceVerificationCheckbox.click();
}
}
});

it('Load Tonedear archive and verify content', async function () {
if (!serviceWorkerAPI) {
it('Load Tonedear archive', async function () {
if (!serviceWorkerAPI && mode === 'serviceworker') {
console.log('\x1b[33m%s\x1b[0m', ' - Following test skipped:');
this.skip();
return;
}

const archiveFiles = await driver.findElement(By.id('archiveFiles'));
await driver.executeScript('arguments[0].style.display = "block";', archiveFiles);

if (!BROWSERSTACK) {
const archiveFiles = await driver.findElement(By.id('archiveFiles'));
await archiveFiles.sendKeys(tonedearBaseFile);
await driver.executeScript('window.setLocalArchiveFromFileSelect();');
const filesLength = await driver.executeScript('return document.getElementById("archiveFiles").files.length');
assert.equal(1, filesLength);
} else {
await driver.executeScript(
'window.setRemoteArchives.apply(this, [arguments[0]]);',
[tonedearBaseFile]
);
await driver.executeScript('var files = arguments[0]; window.setRemoteArchives.apply(this, files);', [tonedearBaseFile]);
await driver.sleep(1300);
}
});

it('Navigate from main page to Android & iOS section', async function () {
// Check for Dialog Box and click any Approve Button in subsequent dialog box
// try {
// const activeAlertModal = await driver.findElement(By.css('.modal[style*="display: block"]'));
// if (activeAlertModal) {
// // console.log('Found active alert modal');
// const approveButton = await driver.findElement(By.id('approveConfirm'));
// await approveButton.click();
// }
// } catch (e) {
// // Do nothing
// console.log('Modal not found within the timeout. Continuing test...');
// }

// Switch to the iframe if the content is inside 'articleContent'
await driver.switchTo().frame('articleContent');
// console.log('Switched to iframe successfully');

// Wait until the link "Android & iOS App" is present in the DOM
await driver.wait(async function () {
const contentAvailable = await driver.executeScript('return document.querySelector(\'a[href="android-ios-ear-training-app"]\') !== null;');
return contentAvailable;
}, 10000); // Increased to 10 seconds for more loading time

// Find the "Android & iOS App" link
const androidLink = await driver.findElement(By.css('a[href="android-ios-ear-training-app"]'));
// Handle security alert if it appears
try {
const securityAlert = await driver.wait(until.elementLocated(By.css('.modal[style*="display: block"]')), 3000);
if (securityAlert) {
const trustSourceButton = await driver.findElement(By.xpath("//button[contains(text(), 'Trust Source')]"));
await trustSourceButton.click();
}
} catch (e) {
// No security alert found, continue with test
}
});

// Test that the element is found
assert(androidLink !== null, 'Android & iOS App link was not found');
it('Navigate to Android & iOS section', async function () {
if (!serviceWorkerAPI && mode === 'serviceworker') {
console.log('\x1b[33m%s\x1b[0m', ' - Following test skipped:');
return;
}

// Scroll the element into view and click it
// await driver.executeScript('arguments[0].scrollIntoView(true);', androidLink);
// await driver.wait(until.elementIsVisible(androidLink), 10000); // Wait until it's visible
await androidLink.click();
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();
await driver.sleep(1000);

// Switch back to the default content
await driver.switchTo().defaultContent();
});
// Verify we're on the correct page
const pageContent = await driver.findElement(By.tagName('body')).getText();
assert.ok(pageContent.includes('Android') || pageContent.includes('iOS'));

it('Verify Android and iOS store images in ' + (mode === 'jquery' ? 'Restricted' : 'ServiceWorker') + ' mode', async function () {
if (!serviceWorkerAPI && mode === 'jquery') {
// Restricted mode test for data URIs
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"]'));

// Verify src attribute has changed to a data URI
const androidSrc = await androidImage.getAttribute('src');
const iosSrc = await iosImage.getAttribute('src');

assert.ok(androidSrc.startsWith('data:image/png;base64,'), 'Android image src is a data URI');
assert.ok(iosSrc.startsWith('data:image/png;base64,'), 'iOS image src is a data URI');

// Compare the first 30 characters of data URIs
const androidDataSnippet = androidSrc.substring(22, 52);
const iosDataSnippet = iosSrc.substring(22, 52);

// Expected snippet for comparison
const expectedAndroidSnippet = 'iVBORw0KGgoAAAANSUhEUg';
const expectedIosSnippet = 'iVBORw0KGgoAAAANSUhEUg';

assert.strictEqual(androidDataSnippet, expectedAndroidSnippet, 'Android image data matches expected');
assert.strictEqual(iosDataSnippet, expectedIosSnippet, 'iOS image data matches expected');
} else if (serviceWorkerAPI && mode === 'serviceworker') {
try {
// ServiceWorker mode test for image loading
await driver.sleep(3000);

const swRegistration = await driver.executeScript('return navigator.serviceWorker.ready');
assert.ok(swRegistration, 'Service Worker is registered');

// console.log('Current URL:', await driver.getCurrentUrl());

// Switch to the iframe that contains the Android and iOS images
const iframe = await driver.findElement(By.id('articleContent'));
await driver.switchTo().frame(iframe);

// 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;

// Check if all images are visible
const visibility = await Promise.all(images.map(async (img) => {
return await img.isDisplayed();
}));
return visibility.every((isVisible) => isVisible);
}, 30000, 'No visible store images found after 30 seconds');

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 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');

const androidWidth = await driver.executeScript('return arguments[0].naturalWidth;', androidImage);
const androidHeight = await driver.executeScript('return arguments[0].naturalHeight;', androidImage);

const iosWidth = await driver.executeScript('return arguments[0].naturalWidth;', iosImage);
const iosHeight = await driver.executeScript('return arguments[0].naturalHeight;', iosImage);

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 the main content after finishing the checks
await driver.switchTo().defaultContent();
} catch (err) {
// 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;
}
if (mode === modes[modes.length - 1]) {
return driver.quit();
}
});
});
Expand Down

0 comments on commit 33cbd3c

Please sign in to comment.