diff --git a/adapters/protractor/src/index.ts b/adapters/protractor/src/index.ts index a5cf55a..cc32365 100644 --- a/adapters/protractor/src/index.ts +++ b/adapters/protractor/src/index.ts @@ -143,16 +143,21 @@ const adapter: UniDriver = { const cm = await (await safeElem()).getAttribute('class'); return cm.split(' ').includes(className); }, - enterValue: async (value: string, options?: EnterValueOptions) => { + enterValue: async ( + value: string, + { delay, shouldClear = true }: EnterValueOptions = {} + ) => { const e = await safeElem(); const disabled = await e.getAttribute("disabled"); // Don't do anything if element is disabled if (disabled) { return; - } - await e.clear(); - if (options?.delay) { - await slowType(element, value, options.delay); + } + if (shouldClear) { + await e.clear(); + } + if (delay) { + await slowType(element, value, delay); } else { await e.sendKeys(value); } diff --git a/adapters/protractor/src/spec.ts b/adapters/protractor/src/spec.ts index f116d0b..2318ae2 100644 --- a/adapters/protractor/src/spec.ts +++ b/adapters/protractor/src/spec.ts @@ -1,24 +1,27 @@ -import { browser, $} from 'protractor'; +import { browser, $ } from 'protractor'; import { SetupFn, runTestSuite, getTestAppUrl } from '@unidriver/test-suite'; import { protractorUniDriver } from '.'; +import { assert } from 'chai'; import { port } from './protractor.conf'; const setup: SetupFn = async (data) => { - await browser.get(`http://localhost:${port}${getTestAppUrl(data)}`); - const driver = protractorUniDriver(() => Promise.resolve($('body'))); + await browser.get(`http://localhost:${port}${getTestAppUrl(data)}`); + const driver = protractorUniDriver(() => Promise.resolve($('body'))); const tearDown = async () => {}; - return {driver, tearDown}; + return { driver, tearDown }; }; describe('protractor', () => { - - runTestSuite({setup}); - + runTestSuite({ setup }); }); describe('protractor specific tests', () => { - + it(`doesn't attempt to clear value when shouldClear is false`, async () => { + const { driver } = await setup({ items: [], initialText: 'hello' }); + await driver + .$('header input') + .enterValue(' world!', { shouldClear: false }); + assert.equal(await driver.$('header input').value(), 'hello world!'); + }); }); - - diff --git a/adapters/puppeteer/src/index.ts b/adapters/puppeteer/src/index.ts index 7158c31..920118c 100644 --- a/adapters/puppeteer/src/index.ts +++ b/adapters/puppeteer/src/index.ts @@ -102,10 +102,10 @@ export const pupUniDriver = ( }; const clearValue = async() => { - const { element, page } = await elem(); - await page.evaluate((element) => { - element.value = ''; - }, element); + const { element } = await elem(); + // Select all input text + await element.click({clickCount: 3}); + await element.press('Backspace'); }; return { @@ -154,7 +154,10 @@ export const pupUniDriver = ( const cm = await (await element.getProperty('classList')).jsonValue(); return Object.keys(cm).map(key => cm[key]).includes(className); }, - enterValue: async (value: string, options?: EnterValueOptions) => { + enterValue: async ( + value: string, + { delay = 0, shouldClear = true }: EnterValueOptions = {} + ) => { const { element } = await elem(); const disabled = await (await element.getProperty('disabled')).jsonValue(); // Don't do anything if element is disabled @@ -162,9 +165,11 @@ export const pupUniDriver = ( return; } await element.focus(); - await clearValue(); + if (shouldClear) { + await clearValue(); + } await element.type(value, { - delay: options?.delay ?? 0, + delay, }); }, pressKey: async (key) => { diff --git a/adapters/puppeteer/src/spec.ts b/adapters/puppeteer/src/spec.ts index 660eb6f..b65896a 100644 --- a/adapters/puppeteer/src/spec.ts +++ b/adapters/puppeteer/src/spec.ts @@ -1,8 +1,14 @@ import * as puppeteer from 'puppeteer'; -import {Browser, Page} from 'puppeteer'; -import {getTestAppUrl, startTestAppServer, SetupFn, runTestSuite} from '@unidriver/test-suite'; -import {pupUniDriver} from './'; -import {Server} from 'http'; +import { Browser, Page } from 'puppeteer'; +import { + getTestAppUrl, + startTestAppServer, + SetupFn, + runTestSuite, +} from '@unidriver/test-suite'; +import { pupUniDriver } from './'; +import { Server } from 'http'; +import { assert } from 'chai'; const port = require('find-free-port-sync')(); @@ -10,36 +16,49 @@ let server: Server; let browser: Browser; let page: Page; -const before = async () => { +const beforeFn = async () => { const args = process.env.CI ? ['--no-sandbox'] : []; const headless = !!process.env.CI; server = await startTestAppServer(port); - browser = await puppeteer.launch({headless, args}); + browser = await puppeteer.launch({ + headless, + args, + }); page = await browser.newPage(); }; -const after = async () => { +const afterFn = async () => { server.close(); await page.close(); await browser.close(); }; const setup: SetupFn = async (params) => { - await page.goto(`http://localhost:${port}${getTestAppUrl(params)}`); - const driver = pupUniDriver({ - page, - selector: 'body' - }); + await page.goto(`http://localhost:${port}${getTestAppUrl(params)}`); + const driver = pupUniDriver({ + page, + selector: 'body', + }); - const tearDown = async () => {}; + const tearDown = async () => {}; - return {driver, tearDown}; + return { driver, tearDown }; }; describe('puppeteer', () => { - runTestSuite({setup, before, after}); + runTestSuite({ setup, before: beforeFn, after: afterFn }); }); describe('puppeteer specific tests', () => { - + before(beforeFn); + after(afterFn); + describe('enterValue', () => { + it(`doesn't attempt to clear value when shouldClear is false`, async () => { + const { driver } = await setup({ items: [], initialText: 'hello' }); + await driver + .$('header input') + .enterValue(' world!', { shouldClear: false }); + assert.equal(await driver.$('header input').value(), 'hello world!'); + }); + }); }); diff --git a/adapters/selenium/src/index.ts b/adapters/selenium/src/index.ts index e8ae326..608b9d6 100644 --- a/adapters/selenium/src/index.ts +++ b/adapters/selenium/src/index.ts @@ -83,11 +83,6 @@ export const seleniumUniDriver = (wep: WebElementGetter): UniDriver } }; - const clearValue = async () => { - const el = await elem(); - return el.getDriver().executeScript(`arguments[0].value = '';`, el); - }; - const slowType = async (element: WebElement, value: string, delay: number) => { const driver = await element.getDriver(); @@ -146,16 +141,21 @@ export const seleniumUniDriver = (wep: WebElementGetter): UniDriver const cl = await el.getAttribute('class'); return cl.split(' ').includes(className); }, - enterValue: async (value: string, options?: EnterValueOptions) => { + enterValue: async ( + value: string, + { delay, shouldClear = true }: EnterValueOptions = {} + ) => { const el = await elem(); const disabled = await el.getAttribute('disabled'); // Don't do anything if element is disabled if (disabled) { return; - } - await clearValue(); - if (options?.delay) { - await slowType(el, value, options.delay); + } + if (shouldClear) { + await el.clear(); + } + if (delay) { + await slowType(el, value, delay); } else { await el.sendKeys(value); } diff --git a/adapters/selenium/src/spec.ts b/adapters/selenium/src/spec.ts index 9d501d4..7644139 100644 --- a/adapters/selenium/src/spec.ts +++ b/adapters/selenium/src/spec.ts @@ -3,63 +3,78 @@ import { seleniumUniDriver } from './'; import { Server } from 'http'; import { ThenableWebDriver, Builder, WebElement, By } from 'selenium-webdriver'; import * as chrome from 'selenium-webdriver/chrome'; -import {SetupFn, runTestSuite, startTestAppServer, getTestAppUrl} from '@unidriver/test-suite'; +import { + SetupFn, + runTestSuite, + startTestAppServer, + getTestAppUrl, +} from '@unidriver/test-suite'; +import { assert } from 'chai'; const port = require('find-free-port-sync')(); let server: Server; let wd: ThenableWebDriver; -const before = async () => { - const headless = !!process.env.CI; - const chromeOptions = new chrome.Options(); +const beforeFn = async () => { + const headless = !!process.env.CI; + const chromeOptions = new chrome.Options(); - if (headless) { - chromeOptions.headless(); - } + if (headless) { + chromeOptions.headless(); + } - server = await startTestAppServer(port); - wd = new Builder() - .forBrowser('chrome') - .setChromeOptions(chromeOptions) - .build(); + server = await startTestAppServer(port); + wd = new Builder() + .forBrowser('chrome') + .setChromeOptions(chromeOptions) + .build(); - await wd.get(`http://localhost:${port}${getTestAppUrl({})}`); - - const driver = seleniumUniDriver(() => { - const el: any = wd.findElement(By.css('body')); - return el as Promise - }); + await wd.get(`http://localhost:${port}${getTestAppUrl({})}`); - await driver.wait(); + const driver = seleniumUniDriver(() => { + const el: any = wd.findElement(By.css('body')); + return el as Promise; + }); + + await driver.wait(); }; -const after = async () => { - server.close(); - await wd.quit(); +const afterFn = async () => { + server.close(); + await wd.quit(); }; const setup: SetupFn = async (data) => { - await wd.get(`http://localhost:${port}${getTestAppUrl(data)}`); - const driver = seleniumUniDriver(() => { - const el: any = wd.findElement(By.css('body')); - return el as Promise - }); + await wd.get(`http://localhost:${port}${getTestAppUrl(data)}`); + const driver = seleniumUniDriver(() => { + const el: any = wd.findElement(By.css('body')); + return el as Promise; + }); - const tearDown = async () => { - // await wd.close(); - }; + const tearDown = async () => { + // await wd.close(); + }; - await driver.wait(); + await driver.wait(); - return {driver, tearDown}; + return { driver, tearDown }; }; describe('selenium', () => { - runTestSuite({setup, before, after}); + runTestSuite({ setup, before: beforeFn, after: afterFn }); }); - describe('selenium specific tests', () => { - + before(beforeFn); + after(afterFn); + describe('enterValue', () => { + it(`doesn't attempt to clear value when shouldClear is false`, async () => { + const { driver } = await setup({ items: [], initialText: 'hello' }); + await driver + .$('header input') + .enterValue(' world!', { shouldClear: false }); + assert.equal(await driver.$('header input').value(), 'hello world!'); + }); + }); }); diff --git a/core/src/index.ts b/core/src/index.ts index 0d58d49..daa007c 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -27,6 +27,7 @@ export type UniDriverList = { export type EnterValueOptions = { delay?: number; // Time to wait between key presses in milliseconds. + shouldClear?: boolean; // Whether to try and clear input value before entering text. (default: true) } export type UniDriver = {