3
3
import { ClientFunction , Selector } from 'testcafe'
4
4
import { queries } from '@testing-library/dom'
5
5
6
+ const SELECTOR_TYPE = ( Selector ( new Function ( ) ) ( ) ) . constructor . name ;
7
+
6
8
7
9
8
10
export async function configureOnce ( options ) {
@@ -25,28 +27,92 @@ Object.keys(queries).forEach(queryName => {
25
27
module . exports [ queryName ] = Selector (
26
28
new Function (
27
29
`
28
- return TestingLibraryDom.${ queryName } (document.body, ...arguments);
30
+ if(!window.tctlReplacer) {
31
+ window.tctlReplacer = function tctlReplacer(key, value) {
32
+ if (value instanceof RegExp)
33
+ return ("__REGEXP " + value.toString());
34
+ else if (typeof value === 'function')
35
+ return ("__FUNCTION " + value.toString());
36
+ else
37
+ return value;
38
+ }
39
+ }
40
+ const els = TestingLibraryDom.${ queryName } (document.body, ...arguments);
41
+ if(!Array.isArray(els)) {
42
+ els.setAttribute('data-tctl-args', JSON.stringify(Array.from(arguments), window.tctlReplacer, 0));
43
+ els.setAttribute('data-tctl-queryname', '${ queryName } ');
44
+ } else {
45
+ els.forEach((el,i) => {
46
+ el.setAttribute('data-tctl-args', JSON.stringify(Array.from(arguments), window.tctlReplacer, 0));
47
+ el.setAttribute('data-tctl-queryname', '${ queryName } ');
48
+ el.setAttribute('data-tctl-index', i);
49
+ });
50
+ }
51
+ return els;
29
52
` ,
30
53
) ,
31
- )
54
+ ) ;
32
55
} )
56
+ function reviver ( key , value ) {
57
+ if ( value . toString ( ) . indexOf ( '__REGEXP ' ) == 0 ) {
58
+ const m = value . split ( '__REGEXP ' ) [ 1 ] . match ( / \/ ( .* ) \/ ( .* ) ? / ) ;
59
+ return new RegExp ( m [ 1 ] , m [ 2 ] || '' ) ;
60
+ } else
61
+ return value ;
62
+ }
63
+
64
+ export const within = async selector => {
65
+ if ( selector instanceof Function ) {
66
+ return within ( selector ( ) ) ;
67
+ }
68
+
69
+ if ( selector . constructor . name === SELECTOR_TYPE ) {
70
+ const el = await selector ;
71
+ const withinQueryName = el . getAttribute ( 'data-tctl-queryname' ) ;
33
72
34
- export const within = selector => {
35
- const sanitizedSelector = selector . replace ( / " / g, "'" )
73
+ const withinArgs = JSON . parse ( el . getAttribute ( 'data-tctl-args' ) , reviver )
74
+ . map ( arg => {
75
+ if ( arg instanceof RegExp ) {
76
+ return arg . toString ( ) ;
77
+ } else if ( arg . toString ( ) . indexOf ( '__FUNCTION ' ) == 0 ) {
78
+ return ( arg . replace ( '__FUNCTION ' , '' ) )
79
+ } else {
80
+ return JSON . stringify ( arg ) ;
81
+ }
82
+ } ) . join ( ', ' ) ;
83
+
84
+ const withinIndexer = el . hasAttribute ( 'data-tctl-index' ) ? `[${ el . getAttribute ( 'data-tctl-index' ) } ]` : '' ;
85
+
86
+ const withinSelectors = { } ;
87
+ Object . keys ( queries ) . forEach ( queryName => {
88
+ withinSelectors [ queryName ] = Selector (
89
+ new Function ( `
90
+
91
+ const {within, ${ withinQueryName } } = TestingLibraryDom;
92
+ const el = ${ withinQueryName } (document.body, ${ withinArgs } )${ withinIndexer } ;
93
+ return within(el).${ queryName } (...arguments);
94
+ `
95
+ ) ) ;
96
+ } ) ;
97
+ return withinSelectors ;
98
+ } else if ( typeof ( selector ) === 'string' ) {
99
+ const sanitizedSelector = selector . replace ( / " / g, "'" ) ;
36
100
37
- const container = { }
101
+ const withinSelectors = { } ;
38
102
39
- Object . keys ( queries ) . forEach ( queryName => {
40
- container [ queryName ] = Selector (
41
- new Function (
42
- `
43
- window.TestcafeTestingLibrary = window.TestcafeTestingLibrary || {}
44
- window.TestcafeTestingLibrary["within_${ sanitizedSelector } "] = window.TestcafeTestingLibrary["within_${ sanitizedSelector } "] || TestingLibraryDom.within(document.querySelector("${ sanitizedSelector } "))
45
- return window.TestcafeTestingLibrary["within_${ sanitizedSelector } "].${ queryName } (...arguments)` ,
46
- ) ,
47
- )
48
- } )
103
+ Object . keys ( queries ) . forEach ( queryName => {
104
+ withinSelectors [ queryName ] = Selector (
105
+ new Function (
106
+ `
107
+ const {within} = TestingLibraryDom;
108
+ return within(document.querySelector("${ sanitizedSelector } ")).${ queryName } (...arguments);
109
+ ` ) ,
110
+ )
111
+ } )
49
112
50
- return container
113
+ return withinSelectors ;
114
+ } else {
115
+ throw new Error ( `"within" only accepts a string or another testing-library query as a parameter. ${ selector } is not one of those` )
116
+ }
51
117
}
52
118
0 commit comments