|
- const config = require('../config');
- const assert = require('assert');
- const scope = require('./scope');
- const pages = require('./pages');
- const selectors = require('./selectors');
-
- const pending = callback => {
- callback(null, 'pending');
- };
-
- const delay = duration => new Promise(resolve => setTimeout(resolve, duration));
-
- const wait = async timeInSeconds => {
- const time = Math.round(parseFloat((''+timeInSeconds).replace(',', '.')) * 1000);
- await delay(time);
- };
-
- const clearStorages = async () => {
- if (scope.context && scope.context.page) {
- await scope.context.page.evaluate(() => {
- localStorage.clear();
- sessionStorage.clear();
- });
- }
- }
-
- const visitPage = async (page) => {
- if (!scope.browser) {
- scope.browser = await scope.driver.launch({
- headless: config.headless,
- slowMo: config.slowMo,
- args: [
- ],
- });
- }
- scope.context.page = await scope.browser.newPage();
- scope.context.page.setViewport({ width: 1280, height: 1024 });
- const url = scope.host + pages[page];
- const visit = await scope.context.page.goto(url, {
- waitUntil: 'networkidle2'
- });
- return visit;
- };
-
- const visitPageIncognito = async (page) => {
- if (!scope.browser) {
- scope.browser = await scope.driver.launch({
- headless: config.headless,
- slowMo: config.slowMo,
- args: [
- '--incognito',
- ],
- });
- }
- scope.context.page = await scope.browser.newPage();
- scope.context.page.setViewport({ width: 1280, height: 1024 });
- const url = scope.host + pages[page];
- const visit = await scope.context.page.goto(url, {
- waitUntil: 'networkidle2'
- });
- return visit;
- };
-
- const clickLink = async (text) => {
- const { page } = scope.context;
- const [link] = await page.$x(`//button[contains(., '${text}')]|//a[contains(., '${text}')]`);
- if (link) {
- await link.click();
- } else {
- throw new Error(
- `Can not find link with text '${text}'`
- );
- }
- };
-
- const clickLinkAt = async (text, wrapper) => {
- const { page } = scope.context;
- const [link] = await page.$x(`//*[contains(@class, '${selectors.wrappers[wrapper]}')]//button[contains(., '${text}')]|a[contains(., '${text}')]`);
- if (link) {
- await link.click();
- } else {
- throw new Error(
- `Can not find link with text '${text}' in the wrapper ${wrapper}`
- );
- }
- };
-
- const pressButton = async text => {
- const { page } = scope.context;
- const [button] = await page.$x(`//button[contains(., '${text}')]|//a[contains(., '${text}')]`);
- if (button) {
- await button.click();
- } else {
- throw new Error(
- `Can not find button with text '${text}'`
- );
- }
- };
-
- const pressButtonAt = async (text, wrapper) => {
- const { page } = scope.context;
- const [button] = await page.$x(`//*[contains(@class, '${selectors.wrappers[wrapper]}')]//button[contains(., '${text}')]|a[contains(., '${text}')]`);
- if (button) {
- await button.click();
- } else {
- throw new Error(
- `Can not find button with text '${text}' in the wrapper ${wrapper}`
- );
- }
- };
-
- const modalOpened = async text => {
- await delay(250);
- const { page } = scope.context;
- const waitModal = await page.waitForSelector('.modal');
- if (!waitModal) {
- throw new Error(
- `Can not find modal`
- );
- }
- await waitModal;
- const [modalWithTitle] = await page.$x(`//*[contains(@class, 'modal')]//*[contains(@class, 'modal-title')][contains(., '${text}')]`);
- if (!modalWithTitle) {
- throw new Error(
- `Can not find modal with title '${text}'`
- );
- }
- }
-
- const modalClosed = async text => {
- await delay(250);
- const { page } = scope.context;
- const [modal] = await page.$x(`//*[contains(@class, 'modal')]`);
- if (modal) {
- const [modalWithTitle] = await page.$x(`//*[contains(@class, 'modal')]//*[contains(@class, 'modal-title')][contains(., '${text}')]`);
- if (modalWithTitle) {
- throw new Error(
- `Modal with title '${text}' still opened`
- );
- }
- }
- }
-
- const shouldSeeText = async text => {
- const { page } = scope.context;
- const content = String(await page.$eval('*', el => el.innerText)).replace(/[\t\s\n\r]+/g, ' ');
- if (!content.includes(text))
- throw new Error(
- `Expected page to contain text: ${text}, but page contains only: ${content}`
- );
- };
-
- const shouldSeeTextAt = async (text, wrapper) => {
- const { page } = scope.context;
- const content = await page.evaluate(selector => {
- const elements = document.querySelectorAll(selector);
- if (!elements) return '';
- const aTexts = [...elements].map(el => el.textContent);
- return aTexts.join(' | ').replace(/[\t\s\n\r]+/g, ' ');
- }, `.${selectors.wrappers[wrapper]}`);
- if (!content.includes(text)) {
- throw new Error(
- `Expected wrapper ${wrapper} to contain text: ${text}, but it contains only: ${content}`
- );
- }
- };
-
- const shouldNotSeeText = async text => {
- const { page } = scope.context;
- const content = String(await page.$eval('*', el => el.innerText)).replace(/[\t\s\n\r]+/g, ' ');
- if (content.includes(text))
- throw new Error(
- `Expected page to not contain text: ${text}, but page contains: ${content}`
- );
- };
-
- const shouldNotSeeTextAt = async (text, wrapper) => {
- const { page } = scope.context;
- const content = await page.evaluate(selector => {
- const elements = document.querySelectorAll(selector);
- if (!elements) return '';
- const aTexts = [...elements].map(el => el.innerText);
- return aTexts.join(' | ').replace(/[\t\s\n\r]+/g, ' ');
- }, `.${selectors.wrappers[wrapper]}:not(.sr-only)`);
- if (content.includes(text)) {
- throw new Error(
- `Expected wrapper ${wrapper} to not contain text: ${text}, but it contains: ${content}`
- );
- }
- };
-
- const buttonShouldBeDisabled = async text => {
- const { page } = scope.context;
- const [button] = await page.$x(`//button[contains(., '${text}')]`);
- if (button) {
- let valueHandle = await button.getProperty('disabled');
- assert.strictEqual(await valueHandle.jsonValue(), true);
- } else {
- throw new Error(
- `Can not find page button with text '${text}'`
- );
- }
- };
-
- const buttonShouldBeEnabled = async text => {
- const { page } = scope.context;
- const [button] = await page.$x(`//button[contains(., '${text}')]`);
- if (button) {
- let valueHandle = await button.getProperty('disabled');
- assert.strictEqual(await valueHandle.jsonValue(), false);
- } else {
- throw new Error(
- `Can not find page button with text '${text}'`
- );
- }
- };
-
- const buttonShouldBeDisabledAt = async (text, wrapper) => {
- const { page } = scope.context;
- const [button] = await page.$x(`//*[contains(@class, '${selectors.wrappers[wrapper]}')]//button[contains(., '${text}')]`);
- if (button) {
- let valueHandle = await button.getProperty('disabled');
- assert.strictEqual(await valueHandle.jsonValue(), true);
- } else {
- throw new Error(
- `Can not find page button with text '${text}' in the wrapper ${wrapper}`
- );
- }
- };
-
- const buttonShouldBeEnabledAt = async (text, wrapper) => {
- const { page } = scope.context;
- const [button] = await page.$x(`//*[contains(@class, '${selectors.wrappers[wrapper]}')]//button[contains(., '${text}')]`);
- if (button) {
- let valueHandle = await button.getProperty('disabled');
- assert.strictEqual(await valueHandle.jsonValue(), false);
- } else {
- throw new Error(
- `Can not find page button with text '${text}' in the wrapper ${wrapper}`
- );
- }
- };
-
- const fillInputField = async (value, field) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- const fieldPresent = await page.waitForSelector(selectors.inputs[field]);
- await fieldPresent;
- await page.focus(`input[name='${field}']`);
- const inputValue = await page.$eval(selectors.inputs[field], el => el.value);
- for (let i = 0; i < inputValue.length; i++) {
- await page.keyboard.press('Backspace');
- }
- await page.type(selectors.inputs[field], value, { delay: 1 });
- await page.$eval(selectors.inputs[field], e => e.blur());
- return;
- };
-
-
- const fillInputFieldAt = async (value, field, wrapper) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- const fieldPresent = await page.waitForSelector(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`);
- await fieldPresent;
- await page.focus(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`);
- const inputValue = await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, el => el.value);
- for (let i = 0; i < inputValue.length; i++) {
- await page.keyboard.press('Backspace');
- }
- await page.type(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, value, { delay: 1 });
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, e => e.blur());
- return;
- };
-
- const setCheckboxField = async (field) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- const fieldPresent = await page.waitForSelector(selectors.inputs[field]);
- await fieldPresent;
- const isChecked = await page.$eval(selectors.inputs[field], el => el.checked)
- if (!isChecked) {
- await page.focus(selectors.inputs[field]);
- await page.$eval(selectors.inputs[field], check => check.click());
- await page.$eval(selectors.inputs[field], e => e.blur());
- }
- return;
- };
-
- const unsetCheckboxField = async (field) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- const fieldPresent = await page.waitForSelector(selectors.inputs[field]);
- await fieldPresent;
- const isChecked = await page.$eval(selectors.inputs[field], el => el.checked)
- if (isChecked) {
- await page.focus(selectors.inputs[field]);
- await page.$eval(selectors.inputs[field], check => check.click());
- await page.$eval(selectors.inputs[field], e => e.blur());
- }
- return;
- };
-
- const setCheckboxFieldAt = async (field, wrapper) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- const fieldPresent = await page.waitForSelector(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`);
- await fieldPresent;
- const isChecked = await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, el => el.checked)
- if (!isChecked) {
- await page.focus(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`);
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, check => check.click());
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, e => e.blur());
- }
- return;
- };
-
- const unsetCheckboxFieldAt = async (field, wrapper) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- const fieldPresent = await page.waitForSelector(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`);
- await fieldPresent;
- const isChecked = await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, el => el.checked)
- if (isChecked) {
- await page.focus(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`);
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, check => check.click());
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.inputs[field]}`, e => e.blur());
- }
- return;
- };
-
- const chooseRadioOption = async (option, field) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- if (!selectors.radio_groups[field]) {
- throw new Error(
- `Radio group '${field}' has no registered selector`
- );
- }
- await shouldSeeText(option);
- if (!selectors.radio_groups[field].options[option]) {
- throw new Error(
- `Radio group '${field}' has no registered option ${option}`
- );
- }
- const isChecked = await page.$eval(`${selectors.radio_groups[field].options[option]}`, el => el.checked)
- if (!isChecked) {
- await page.focus(`${selectors.radio_groups[field].options[option]}`);
- await page.$eval(`${selectors.radio_groups[field].options[option]}`, check => check.click());
- await page.$eval(`${selectors.radio_groups[field].options[option]}`, e => e.blur());
- }
- };
-
- const chooseRadioOptionAt = async (option, field, wrapper) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- if (!selectors.radio_groups[field]) {
- throw new Error(
- `Radio group '${field}' has no registered selector`
- );
- }
- await shouldSeeText(option);
- if (!selectors.radio_groups[field].options[option]) {
- throw new Error(
- `Radio group '${field}' has no registered option ${option}`
- );
- }
- const isChecked = await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.radio_groups[field].options[option]}`, el => el.checked)
- if (!isChecked) {
- await page.focus(`.${selectors.wrappers[wrapper]} ${selectors.radio_groups[field].options[option]}`);
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.radio_groups[field].options[option]}`, check => check.click());
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.radio_groups[field].options[option]}`, e => e.blur());
- }
- };
-
- const setCheckboxGroupOption = async (option, field) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- if (!selectors.checkbox_groups[field]) {
- throw new Error(
- `Checkbox group '${field}' has no registered selector`
- );
- }
- await shouldSeeText(option);
- if (!selectors.checkbox_groups[field].options[option]) {
- throw new Error(
- `Checkbox group '${field}' has no registered option ${option}`
- );
- }
- const isChecked = await page.$eval(`${selectors.checkbox_groups[field].options[option]}`, el => el.checked)
- if (!isChecked) {
- await page.focus(`${selectors.checkbox_groups[field].options[option]}`);
- await page.$eval(`${selectors.checkbox_groups[field].options[option]}`, check => check.click());
- await page.$eval(`${selectors.checkbox_groups[field].options[option]}`, e => e.blur());
- }
- };
-
- const unsetCheckboxGroupOption = async (option, field) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- if (!selectors.checkbox_groups[field]) {
- throw new Error(
- `Checkbox group '${field}' has no registered selector`
- );
- }
- await shouldSeeText(option);
- if (!selectors.checkbox_groups[field].options[option]) {
- throw new Error(
- `Checkbox group '${field}' has no registered option ${option}`
- );
- }
- const isChecked = await page.$eval(`${selectors.checkbox_groups[field].options[option]}`, el => el.checked)
- if (isChecked) {
- await page.focus(`${selectors.checkbox_groups[field].options[option]}`);
- await page.$eval(`${selectors.checkbox_groups[field].options[option]}`, check => check.click());
- await page.$eval(`${selectors.checkbox_groups[field].options[option]}`, e => e.blur());
- }
- };
-
- const setCheckboxGroupOptionAt = async (option, field, wrapper) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- if (!selectors.checkbox_groups[field]) {
- throw new Error(
- `Checkbox group '${field}' has no registered selector`
- );
- }
- await shouldSeeText(option);
- if (!selectors.checkbox_groups[field].options[option]) {
- throw new Error(
- `Checkbox group '${field}' has no registered option ${option}`
- );
- }
- const isChecked = await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`, el => el.checked)
- if (!isChecked) {
- await page.focus(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`);
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`, check => check.click());
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`, e => e.blur());
- }
- };
-
- const unsetCheckboxGroupOptionAt = async (option, field, wrapper) => {
- const { page } = scope.context;
- await shouldSeeText(field);
- if (!selectors.checkbox_groups[field]) {
- throw new Error(
- `Checkbox group '${field}' has no registered selector`
- );
- }
- await shouldSeeText(option);
- if (!selectors.checkbox_groups[field].options[option]) {
- throw new Error(
- `Checkbox group '${field}' has no registered option ${option}`
- );
- }
- const isChecked = await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`, el => el.checked)
- if (isChecked) {
- await page.focus(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`);
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`, check => check.click());
- await page.$eval(`.${selectors.wrappers[wrapper]} ${selectors.checkbox_groups[field].options[option]}`, e => e.blur());
- }
- };
-
- const jsonViewContains = async (field, value) => {
- const { page } = scope.context;
- const jsonViewPresent = await page.waitForSelector('.react-json-view');
- await jsonViewPresent;
- const aRes = await page.$$eval('.variable-row', options => options.map(option => option.textContent))
- const keyWrap = isNaN(field) ? '"' : ''
- const valWrap = isNaN(value) ? '"' : ''
- let res = false;
- aRes.forEach(e => {
- if ('true' === value || 'false' === value) {
- if (e.includes(keyWrap + field + keyWrap) && e.includes('bool' + value)) {
- res = true;
- }
- } else {
- if (e.includes(keyWrap + field + keyWrap) && e.includes(valWrap + value + valWrap)) {
- res = true;
- }
- }
- });
- if (!res) {
- throw new Error(
- `Expected jsonView var: ${field} should contains ${value}, but given ${aRes}`
- );
- }
- };
-
- const jsonViewContainsAt = async (fieldName, rowKey, rowValue) => {
- const { page } = scope.context;
- const [fieldWrapper] = await page.$x(`//*[contains(@class, 'react-json-view')]//*[contains(., '${fieldName}')]//preceding::*[contains(@class, 'object-key-val')][1]`);
- const aRes = await fieldWrapper.$$eval('.variable-row', options => options.map(option => option.textContent))
- const keyWrap = isNaN(rowKey) ? '"' : ''
- const valWrap = isNaN(rowValue) ? '"' : ''
- let res = false;
- aRes.forEach(e => {
- if ('true' === rowValue || 'false' === rowValue) {
- if (e.includes(keyWrap + rowKey + keyWrap) && e.includes('bool' + rowValue)) {
- res = true;
- }
- } else {
- if (e.includes(keyWrap + rowKey + keyWrap) && e.includes(valWrap + rowValue + valWrap)) {
- res = true;
- }
- }
- });
- if (!res) {
- throw new Error(
- `Expected jsonView var: ${fieldName} should contains: ${rowKey} => ${rowValue}, but given ${aRes}`
- );
- }
- };
-
- module.exports = {
- pending,
- delay,
- wait,
- clearStorages,
- visitPage,
- visitPageIncognito,
- shouldSeeText,
- shouldSeeTextAt,
- shouldNotSeeText,
- shouldNotSeeTextAt,
- clickLink,
- clickLinkAt,
- pressButton,
- pressButtonAt,
- buttonShouldBeDisabled,
- buttonShouldBeEnabled,
- buttonShouldBeDisabledAt,
- buttonShouldBeEnabledAt,
- fillInputField,
- setCheckboxField,
- unsetCheckboxField,
- fillInputFieldAt,
- setCheckboxFieldAt,
- unsetCheckboxFieldAt,
- chooseRadioOption,
- chooseRadioOptionAt,
- setCheckboxGroupOption,
- unsetCheckboxGroupOption,
- setCheckboxGroupOptionAt,
- unsetCheckboxGroupOptionAt,
- modalOpened,
- modalClosed,
- jsonViewContains,
- jsonViewContainsAt,
- };
|