|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- 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 = await page.content();
- 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 [el] = await page.$x(`//*[contains(@class, '${selectors.wrappers[wrapper]}')]//*[contains(., '${text}')]`);
- if (!el) {
- const content = await page.content();
- throw new Error(
- `Expected wrapper ${wrapper} to contain text: ${text}, but page contains only: ${content}`
- );
- }
- };
-
- const shouldNotSeeText = async text => {
- const { page } = scope.context;
- const content = await page.content();
- 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 [el] = await page.$x(`//*[contains(@class, '${selectors.wrappers[wrapper]}')]//*[contains(., '${text}')]`);
- if (el) {
- const content = await page.content();
- throw new Error(
- `Expected wrapper ${wrapper} to not contain text: ${text}, but page 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,
- };
|