Tell Copilot Where To Find Test Selectors

Use Copilot instructions file to point each end-to-end spec at the top-level page source file.

I have shown how to use Copilot instructions file to generate better end-to-end Cypress tests. In this blog post I will show a specific trick I use to make my test writing a lot more precise and much faster. When we are writing end-to-end tests, we constantly need to look up the best test selectors to use to find elements on the page. By default, Copilot LLM has no idea about specific format of our page. Copilot simply uses "generic" trained model. For example, I am testing this "Players" page. It should show a hint message explaining to the user what to do.

The players page showing the hint

As always, I describe what I am trying to achieve and guide AI using inline comments

cypress/e2e/players.cy.ts
1
2
3
4
5
6
7
8
9
describe('Players', () => {
it('shows zero players message', () => {
cy.visit('/player/')
// you should see the players page

// the page should give us a hint message

})
})

What do you think Copilot would do for the two empty lines?

The first Copilot suggestion

Copilot model "thinks" that the most likely code completion after the comment "// you should see the players page" is cy.contains('Players'). This is extremely flaky test selector. It is NOT specific to the page and is likely to pass accidentally. What about the second comment?

The second Copilot suggestion

Copilot inserts cy.contains('No players found') after the comment "// the page should give us a hint message". This is likely to be the effect of the test title "shows zero players message" and not what we are trying to do! It is not what the page has, so the test fails immediately

The generated test fails

In the ideal world we could use the real page DOM markup, as I have shown in the video Add Page HTML To Fix A Cypress Test Error Using Cursor AI. But we can do this in a simpler way. We know that the spec cypress/e2e/players.cy.ts mostly interacts with the page src/routes/player/index.tsx of our application (the end-to-end tests live in the same repo as the app itself). If you look at the source file, can you tell me how the elements in question should be selected?

the source page markup

I haven't even told you that this app uses Qwik framework - since it does not matter and should not affect your end-to-end tests. Yet, you see the obvious candidates for test selectors for our test. We will use the data-cy attributes which are stable and are meant for testing.

data-cy attributes make for good stable test selectors

Tip: if we keep the src/routes/player/index.tsx file open in one of our VSCode tabs, Copilot should be able to use it to find test selectors. But we want to make sure everyone can find the selectors, even when they are unaware of the project's structured.

This is where the Copilot instruction file comes in. We simply can "tell" Copilot the main source files to use when working with specific spec files.

.github/copilot-instructions.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
## Use Cypress syntax

This repo uses Cypress to implement end-to-end tests.

...

## Spec file and selectors

When editing the following spec files, look up the relevant element selectors, markup,
and values from the given files:

- cypress/e2e/history.cy.js - src/routes/history/index.tsx
- cypress/e2e/history-games.cy.ts - src/routes/history/game/[id]/index.tsx
- cypress/e2e/finish-page.cy.ts - src/routes/finish/index.tsx and src/components/finished-game.tsx
- cypress/e2e/finish-the-game.cy.ts - src/routes/finish/index.tsx
- cypress/e2e/players.cy.ts - src/routes/player/index.tsx
- cypress/e2e/carousel.cy.ts - src/components/screenshots.tsx

Let's see what Copilot suggests now

Copilot picks data-cy test selectors

Note: you might need to enable Copilot instructions file in your VSCode Copilot settings.

VSCode Copilot setting to enable the instructions file

See how to write Copilot instructions file in the official docs