Skip to content

Commit

Permalink
fix: queries when Simmer cannot create selector
Browse files Browse the repository at this point in the history
When Simmer fails to create a unique selector, usually because it would
need to go to a higher depth than 3 to generate it, queries will fail.

Simmer was added to allow refetching of elements when they become stale
but if it fails it would be better to fallback to using WebElement JSONs
to create the WebdriverIO.Element instances so that the queries don't
fail. When falling back to using WebElement JSONs refetching elements
won't be possible anymore.

Maybe in future we want to allow users to configure Simmer themselves so
that they can set the depth etc. We may also want to add an info log at
some point.
  • Loading branch information
olivierwilkinson committed Jun 13, 2021
1 parent 14cd90f commit 768d2ab
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
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()
})
})

0 comments on commit 768d2ab

Please sign in to comment.