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
48 changes: 40 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,53 @@ function executeQuery(
}

if (Array.isArray(result)) {
return done(result.map((element) => ({selector: window.Simmer(element)})))
return done(
result.map((element) => ({
selector: window.Simmer(element),
element,
})),
)
}

return done({selector: window.Simmer(result)})
return done({
selector: window.Simmer(result),
element: result,
})
})()
}

function createQuery(element: ElementBase, queryName: string) {
/*
Always include element key "element-6066-11e4-a52e-4f735466cecf": WebdriverIO
checks whether this key is a string to determine if the selector is actually a
WebElement JSON. If the selector is a WebElement JSON it uses it to create a new
Element. There are valid WebElement JSONs that exclude the key but can be turned
into Elements, such as { ELEMENT: elementId }; this can happen in setups that
aren't generated by @wdio/cli.
*/
function createElement(
container: ElementBase,
result: {selector: string | false; element: any},
) {
// use selector if possible so that element can be refetched
if (result.selector) {
return container.$(result.selector)
}

// fallback to using WebElement JSON if selector could not be created
return container.$({
'element-6066-11e4-a52e-4f735466cecf': '',
...result.element,
})
}

function createQuery(container: ElementBase, queryName: string) {
return async (...args: any[]) => {
await injectDOMTestingLibrary(element)
await injectDOMTestingLibrary(container)

const result = await element.executeAsync(
const result = await container.executeAsync(
executeQuery,
queryName,
element,
container,
...args.map(serializeArg),
)

Expand All @@ -151,10 +183,10 @@ function createQuery(element: ElementBase, queryName: string) {
}

if (Array.isArray(result)) {
return Promise.all(result.map(({selector}) => element.$(selector)))
return Promise.all(result.map(createElement.bind(null, container)))
}

return element.$(result.selector)
return createElement(container, result)
}
}

Expand Down
21 changes: 21 additions & 0 deletions test-app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,27 @@ <h2>getAllByText</h2>
<h2>navigate</h2>
<a href="page2.html">Go to Page 2</a>
</section>
<section>
<h2>Simmer</h2>
<div>
<div>
<div>
<div>
High depth non-specific div one
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
High depth non-specific div two
</div>
</div>
</div>
</div>
</section>
<!-- Prettier unindents the script tag below -->
<script>
document
Expand Down
12 changes: 12 additions & 0 deletions test/async/queries.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,16 @@ describe('queries', () => {
JSON.stringify(await refetchElement(button, 'click')),
)
})

it('getAllBy works when Simmer cannot create a unique selector', async () => {
const {getAllByText} = setupBrowser(browser)

expect(await getAllByText(/High depth non-specific div/)).toHaveLength(2)
})

it('getBy works when Simmer cannot create a unique selector', async () => {
const {getByText} = setupBrowser(browser)

expect(await getByText('High depth non-specific div one')).not.toBeNull()
})
})