+
+```
+
+Because `findAllNodes` traverses the fiber tree, the following selectors will correctly identify test host nodes:
+
+* ✓ `Parent#parent`
+* ✓ `Parent Child#child`
+* ✓ `Child#child`
+
+## `getFindAllNodesFailureDescription`
+
+### Debugging failed selectors
+
+If a test fails because an expected match was not found, it is useful to provide a developer with actionable feedback. Here is a selector that would not find a match given the example app above:
+
+```
+await wwwPage.click('Header PageTitle Link#link');
+```
+
+In this case, the e2e framework knows that a match was expected (because the `click` action was used) so it should provide the user with an actionable error message. `getFindAllNodesFailureDescription` can help with this.
+
+```
+getFindAllNodesFailureDescription(document.body, [
+ createComponentSelector(require("Header.react")),
+ createComponentSelector(require("PageTitle.react")),
+ createComponentSelector(require("Link.react")),
+ createTestNameSelector("link"),
+]);
+```
+
+In this case the returned description might be something like the following (depending on the `displayName` values for the specified React components):
+
+```
+``findAllNodes` was able to match part of the selector:
+ `Header` > `PageTitle
+`
+No matching component was found for:
+ `Link``
+```
+
+## `findBoundingRects()`
+
+Test may want to take screenshot snapshots of a component:
+
+```
+await expect('Navigation.react').toMatchScreenshot();
+```
+
+We could use the `findBoundingRects` API for this:
+
+```
+const rects = findBoundingRects(document.body, [
+ createComponentSelector(require("Navigation.react")),
+]);
+```
+
+User Puppeteer as an example then, we might do:
+
+```
+const rect = merge(rects);
+
+await page.screenshot({
+ clip: {
+ x: rect.left,
+ y: rect.top,
+ width: rect.width,
+ height: rect.height
+ }
+});
+```
+
+## `observeVisibleRects()`
+
+### Verifying that an element was rendered
+
+The `findAllNodes` example above could be rewritten to use the `observeVisibleRects` API instead. This change would likely encompass a larger host subtree but would also eliminate the need for a `data-testname`. For example:
+
+```
+await expect('Navigation').toBeVisible();
+```
+
+The selector above could be parsed and converted to use the `observeVisibleRects` API:
+
+```
+let matched = false;
+
+const callback = recs => {
+ recs.forEach(({ ratio: number, rect: Rect }) => {
+ // Some business logic to approve or reject based on the ratio, e.g.
+ if (ratio > 0.5) {
+ matched = true;
+ }
+ });
+};
+
+const { disconnect } = observeVisibleRects(
+ document.body,
+ [createComponentSelector(require("Navigation.react"))],
+ callback
+);
+
+// Optionally wait some amount of time until the element becomes visible.
+
+disconnect();
+
+if (!matched) {
+ // Throw error
+}
+```
+
+## `focusWithin()`
+
+### Clicking on a link
+
+Given the above example code, we could click on the first link within the `Navigation` menu using the `focusWithint` API:
+
+```
+focusWithin(document.body, [
+ createComponentSelector(require("Navigation.react")),
+]);
+
+// document.activeElement is now the 1st focusable host instance in Navigation.
+```
+
+User Puppeteer as an example then, we might do:
+
+```
+`const`` element ``=`` await page``.``evaluateHandle``(()`` ``=>`` document``.``activeElement``);
+``await element.click();`
+```
+
+### Entering text into a search input
+
+Given the above example code, we could use the `focusWithint` API to search:
+
+```
+focusWithin(document.body, [
+ createComponentSelector(require("SearchInput.react")),
+]);
+
+// document.activeElement is now the 1st focusable host instance in SearchInput.
+```
+
+User Puppeteer as an example then, we might do:
+
+```
+await page.keyboard.type("Type this into the focused element...");
+```
+
+# Drawbacks
+
+* Supporting all renderers will require a more constrained API than if we targeted only one renderer (e.g. DOM).
+
+# Alternatives
+
+* Adapter strategy (like Enzyome uses). This has proven increasing hard to maintain as React releases new updates.
+* Accessibility focused strategy (like Testing Library uses). TL shares a lot of similarities with this test selector proposal. This proposal offers a few advantages though, including better support for portals and a unified testing API to be adopted by any React renderer.
+
+# Adoption strategy
+
+* Work with Jest e2e library maintainers to adopt this new API.
+* Adoption beyond this is optional and can move at its own pace.
+
+Note that to use the test selector API at scale, you might want to use a Webpack alias (or equivalent) when building your test target:
+```js
+module.exports = {
+ // ...
+ resolve: {
+ // ...
+ alias: {
+ // ...
+ 'react-dom$': 'react-dom/testing',
+ },
+ // ...
+ },
+ // ...
+};
+```
+
+# How we teach this
+
+Much of the above RFC (usage examples) could be converted to user-facing documentation. We will probably want to write an addition introduction explaining ways to structure tests, and testing methodology.
+
+# Unresolved questions
+
+* What are the best ways to require component definitions to passed to `createComponentSelector`?
+* Will existing test libraries (other than Jest e2e) adopt this new API?
+* More (to be uncovered by this RFC?)
\ No newline at end of file