/**
* Copyright © 2016-2020 Threema GmbH (https://threema.ch/).
*
* This file is part of Threema Web.
*/
// tslint:disable:no-reference
// tslint:disable:no-console
// tslint:disable:no-unused-expression
///
import { expect } from 'chai';
import { Builder, By, Key, until, WebDriver, WebElement } from 'selenium-webdriver';
import * as TermColor from 'term-color';
// Script arguments
const browser = process.argv[2];
const filterQuery = process.argv[3];
// Type aliases
type Testfunc = (driver: WebDriver) => void;
// Shared selectors
const composeArea = By.id('composeDiv');
const emojiKeyboard = By.css('.emoji-keyboard');
const emojiTrigger = By.css('.emoji-trigger');
/**
* Helper function to extract text.
*/
async function extractText(driver: WebDriver): Promise {
const script = `return window.composeArea.get_text();`;
return driver.executeScript(script);
}
/**
* Helper function to send a KeyDown event.
*/
async function sendKeyDown(driver: WebDriver, key: string): Promise {
const script = `
const e = document.createEvent('HTMLEvents');
e.initEvent('keydown', false, true);
e.key = '${key}';
const element = document.querySelector("div.compose");
element.dispatchEvent(e);
`;
return driver.executeScript(script);
}
/**
* Helper function to send a KeyUp event.
*/
async function sendKeyUp(driver: WebDriver, key: string): Promise {
const script = `
const e = document.createEvent('HTMLEvents');
e.initEvent('keyup', false, true);
e.key = '${key}';
const element = document.querySelector("div.compose");
element.dispatchEvent(e);
`;
return driver.executeScript(script);
}
/**
* The emoji trigger should toggle the emoji keyboard.
*/
async function buttonTogglesEmojiSelector(driver: WebDriver) {
// Initially not visible
expect(
await driver.findElement(emojiKeyboard).isDisplayed(),
).to.be.false;
// Show
await driver.findElement(emojiTrigger).click();
expect(
await driver.findElement(emojiKeyboard).isDisplayed(),
).to.be.true;
// Hide
await driver.findElement(emojiTrigger).click();
expect(
await driver.findElement(emojiKeyboard).isDisplayed(),
).to.be.false;
}
/**
* Insert two emoji and some text.
*/
async function insertEmoji(driver: WebDriver) {
// Show emoji keyboard
await driver.findElement(emojiTrigger).click();
// Insert woman zombie emoji
await driver.findElement(By.css('.em[data-s=":woman_zombie:"]')).click();
// Insert text
await driver.findElement(composeArea).sendKeys('hi');
// Insert beer
await driver.findElement(By.className('em-food')).click();
const elem = await driver.findElement(By.css('.em[data-s=":beers:"]'));
await elem.click();
// Validate emoji
const emoji = await driver.findElement(composeArea).findElements(By.xpath('*'));
expect(emoji.length).to.equal(2);
expect(await emoji[0].getAttribute('data-c')).to.equal('1f9df-200d-2640-fe0f'); // woman zombie
expect(await emoji[1].getAttribute('data-c')).to.equal('1f37b'); // clinking beer mugs
// Validate text
const html = await driver.findElement(composeArea).getAttribute('innerHTML');
expect(/>hi
= [
['Show and hide emoji selector', buttonTogglesEmojiSelector],
['Insert emoji and text', insertEmoji],
['Insert three lines of text', insertNewline],
['Regression test #574', regression574],
['Regression test #671', regression671],
['Regression test #672', regression672],
['Insert emoji through shortcode', insertEmojiWithShortcode],
];
// Test runner
const TEST_URL = 'http://localhost:7777/tests/ui/compose_area.html';
(async function() {
const driver: WebDriver = await new Builder().forBrowser(browser).build();
driver.manage().setTimeouts({implicit: 1000, pageLoad: 30000, script: 30000});
let i = 0;
let success = 0;
let failed = 0;
let skipped = 0;
console.info('\n====== THREEMA WEB UI TESTS ======\n');
if (filterQuery !== undefined) {
console.info(`Filter query: "${filterQuery}"\n`);
}
try {
// Initial pageload to ensure bundles are generated
await driver.get(TEST_URL);
for (const [name, testfunc] of TESTS) {
try {
if (filterQuery === undefined || name.toLowerCase().indexOf(filterQuery.toLowerCase()) !== -1) {
i++;
console.info(TermColor.blue(`» ${i}: Running test: ${name}`));
await driver.get(TEST_URL);
await testfunc(driver);
success++;
} else {
skipped++;
}
} catch (e) {
console.error(TermColor.red(`\nTest failed:`));
console.error(e);
failed++;
}
}
} finally {
await driver.quit();
}
const colorFunc = failed > 0 ? TermColor.red : TermColor.green;
console.info(colorFunc(`\nSummary: ${i} tests run, ${success} succeeded, ${failed} failed, ${skipped} skipped`));
process.exit(failed > 0 ? 1 : 0);
})();