Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .testcaferc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"clientScripts": [
"./node_modules/@testing-library/dom/dist/@testing-library/dom.umd.js"
],
"src": "tests/testcafe/**/*.js",
"browsers": [
"chrome:headless",
Expand Down
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ install: npm ci
script: npm run validate
after_success: npx semantic-release
branches:
only: master
only:
- master
- next
1,482 changes: 926 additions & 556 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,25 @@
"license": "ISC",
"dependencies": {
"@babel/runtime": "^7.4.3",
"@testing-library/dom": "^5.0.1",
"testcafe": "^1.1.2"
"@testing-library/dom": "^6.1.0",
"testcafe": "^1.4.1"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-plugin-testcafe": "^0.2.1",
"kcd-scripts": "^1.2.1",
"npm-run-all": "^4.1.5",
"semantic-release": "^15.13.3",
"semantic-release": "^16.0.0-beta.22",
"serve": "^11.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/testing-library/testcafe-testing-library.git"
},
"release": {
"branches": [
"master",
"next"
]
}
}
53 changes: 7 additions & 46 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,25 @@
/* eslint-disable no-eval */
/* eslint-disable no-new-func */
import fs from 'fs'
import path from 'path'
import { ClientFunction, Selector } from 'testcafe'
import { queries } from '@testing-library/dom'

const DOM_TESTING_LIBRARY_UMD_PATH = path.join(
require.resolve( '@testing-library/dom' ),
'../../',
'dist/@testing-library/dom.umd.js',
)
const DOM_TESTING_LIBRARY_UMD = fs.readFileSync(DOM_TESTING_LIBRARY_UMD_PATH).toString()


export async function configureOnce(options) {
const { content } = configure(options);

await new ClientFunction(new Function(content))();
}

export function configure(options) {

export async function configure(options, t) {
const configFunction =
`
window.TestingLibraryDom.configure(${JSON.stringify(options)});
`;
await new ClientFunction(new Function(configFunction))();

if (t) {
t.testRun.injectable.scripts.push('/testcafe-testing-library-config.js');
t.testRun.session.proxy.GET('/testcafe-testing-library-config.js', { content: configFunction, contentType: 'application/x-javascript' })
}

}

export async function addTestcafeTestingLibrary(t) {
// inject for 1st pageload. Then just use injectables for subsequent page loads.
// eslint-disable-next-line
const inject = ClientFunction(
() => {
// eslint-disable-next-line no-undef
window.eval(script)
},
{
dependencies: { script: DOM_TESTING_LIBRARY_UMD },
},
)

await inject.with({ boundTestRun: t })();

//and for subsequent pageloads:
t.testRun.injectable.scripts.push('/dom-testing-library.js');
t.testRun.session.proxy.GET('/dom-testing-library.js', { content: DOM_TESTING_LIBRARY_UMD, contentType: 'application/x-javascript' })

if (addTestcafeTestingLibrary.options) {
await configure(addTestcafeTestingLibrary.options, t);
}

return { content: configFunction };
}

// eslint-disable-next-line no-shadow
addTestcafeTestingLibrary.configure = function configure(options) {
addTestcafeTestingLibrary.options = { ...options };
return addTestcafeTestingLibrary;
}

Object.keys(queries).forEach(queryName => {
module.exports[queryName] = Selector(
Expand Down
7 changes: 3 additions & 4 deletions tests/testcafe/configure.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/* eslint-disable import/named */
import { configure, getByTestId, getByText, addTestcafeTestingLibrary } from '../../src'

import { configure, configureOnce, getByTestId, getByText } from '../../src'


// eslint-disable-next-line babel/no-unused-expressions
fixture`configure`.beforeEach(addTestcafeTestingLibrary.configure({ testIdAttribute: 'data-automation-id' }))
fixture`configure`.clientScripts(configure({ testIdAttribute: 'data-automation-id' }))
.page`http://localhost:13370`


Expand All @@ -21,6 +20,6 @@ test('still works after browser page load', async t => {
})

test('can be used standalone', async t => {
await configure({ testIdAttribute: 'data-other-test-id' });
await configureOnce({ testIdAttribute: 'data-other-test-id' });
await t.click(getByTestId('other-id'));
})
9 changes: 7 additions & 2 deletions tests/testcafe/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
getByTestId,
getAllByText,
queryAllByText,
addTestcafeTestingLibrary,

} from '../../src/'

// eslint-disable-next-line babel/no-unused-expressions
fixture`selectors`.beforeEach(addTestcafeTestingLibrary)
fixture`selectors`
.page`http://localhost:13370`

test('getByPlaceHolderText', async t => {
Expand Down Expand Up @@ -64,6 +64,11 @@ test('still works after browser page load', async t => {
.expect(getByText('second page').exists).ok()
})

test('still works after reload', async (t) => {
await t.eval(() => location.reload(true));
await t.expect(getByText('getByText').exists).ok();
});

test.skip('getByTestId only throws the error message', async t => {
const testId = 'Some random id'
const errorMessage = `Unable to find an element by: [data-testid="${testId}"]`
Expand Down
12 changes: 6 additions & 6 deletions tests/testcafe/within.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import {Selector} from 'testcafe'
import {within, addTestcafeTestingLibrary} from '../../src'
import { Selector } from 'testcafe'
import { within } from '../../src'

// eslint-disable-next-line babel/no-unused-expressions
fixture`within`.beforeEach(addTestcafeTestingLibrary)
fixture`within`
.page`http://localhost:13370`

test('getByText within container', async t => {
const {getByText} = await within('#nested')
const { getByText } = await within('#nested')
await t
.click(getByText('Button Text'))
.expect(Selector('button').withExactText('Button Clicked').exists)
.ok()
})

test("queryByPlaceholder doesn't find anything", async t => {
const {queryByPlaceholderText} = await within('#nested')
const { queryByPlaceholderText } = await within('#nested')

await t.expect(queryByPlaceholderText('Placeholder Text').exists).notOk()
})

test('quotes in selector', async t => {
const {getByText} = await within('div[id="nested"]')
const { getByText } = await within('div[id="nested"]')

await t
.click(getByText('Button Text'))
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/__snapshots__/selectors.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

exports[`exports expected selectors 1`] = `
Array [
"configureOnce",
"configure",
"addTestcafeTestingLibrary",
"within",
"queryAllByLabelText",
"getAllByLabelText",
Expand Down Expand Up @@ -41,8 +41,8 @@ Array [
"getAllByTitle",
"findAllByTitle",
"findByTitle",
"queryByRole",
"queryAllByRole",
"queryByRole",
"getAllByRole",
"getByRole",
"findAllByRole",
Expand Down
17 changes: 8 additions & 9 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import {BoundFunction, IConfig, queries} from '@testing-library/dom';
import {Selector, t} from 'testcafe';
import { BoundFunction, IConfig, queries } from '@testing-library/dom';
import { Selector, t, ClientScript } from 'testcafe';

export function addTestcafeTestingLibrary(
testController: typeof t
): Promise<void>;
export function configureOnce(
options: Pick<IConfig, 'testIdAttribute'>
): Promise<void>

export function configure(
options: Pick<IConfig, 'testIdAttribute'>,
testController: typeof t
): Promise<void>;
options: Pick<IConfig, 'testIdAttribute'>
): ClientScript;

export type TestcafeBoundFunction<T> = (...params: Parameters<BoundFunction<T>>) => Selector;
export type TestcafeBoundFunctions<T> = {[P in keyof T]: TestcafeBoundFunction<T[P]>};
export type TestcafeBoundFunctions<T> = { [P in keyof T]: TestcafeBoundFunction<T[P]> };

export function within(selector: string): Promise<TestcafeBoundFunctions<typeof queries>>;

Expand Down