Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin E2E: Make it possible to test query editor in panel edit page #551

Merged
merged 25 commits into from
Nov 24, 2023

Conversation

sunker
Copy link
Contributor

@sunker sunker commented Nov 21, 2023

What this PR does / why we need it:
This PR adds fixtures, models and expect matchers that enable testing a data source query editor in the panel edit page.

A few things to note:

  • Added two playwright tests files that tests the google sheets data source. One of them are doing full E2E tests, i.e requests are hitting downstream APIs. The other file is only testing the frontend by mocking the Grafana backend.
  • I've made the GH action matrix multi-dimensional so that tests are not only targeting multiple versions of Grafana, but also multiple versions of the Google Sheets data source.

Sorry for the large amount of files changed. Wanted the PR to include all the pieces that is needed to test a query editor so one can review this as a full feature. Let me know if you want me to try and split the PR.

Which issue(s) this PR fixes:
Part of grafana/grafana#78078

Fixes #

Special notes for your reviewer:

Copy link

github-actions bot commented Nov 21, 2023

Hello! 👋 This repository uses Auto for releasing packages using PR labels.

✨ This PR can be merged. It will not be considered when calculating future versions of the npm packages and will not appear in the changelogs.

@sunker sunker added the no-changelog Don't include in changelog and version calculations label Nov 21, 2023
@sunker sunker marked this pull request as ready for review November 21, 2023 08:48
@sunker sunker requested review from mckn, leventebalogh and jackw and removed request for mckn November 21, 2023 08:48
@@ -1,7 +1,8 @@
{
"compilerOptions": {
"outDir": "./dist",
"declaration": true
"declaration": true,
"stripInternal": true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like some types to be internal so added this option. Maybe this should go in the base config? Thoughts @jackw?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity - how do we decide which types should be private and which ones should be public? I sometimes find it useful during development to have access to as many types as possible when working with a package, while on the other hand it can tie our hands if we expose too much, as we can hardly change what a lot of people depend on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Think I just don't want to overload consumer with irrelevant types etc. But may be better to save this for later.

@sunker sunker changed the title Query editor Plugin E2E: Make it possible to test query editor in panel edit page Nov 21, 2023
Copy link
Collaborator

@leventebalogh leventebalogh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, I really like the explanatory comments, they helped a lot with reviewing. 👏 Generally looks good to me, left a few comments.

packages/plugin-e2e/src/api.ts Outdated Show resolved Hide resolved
packages/plugin-e2e/src/api.ts Outdated Show resolved Hide resolved
packages/plugin-e2e/src/api.ts Outdated Show resolved Hide resolved
*
* If you have tests that depend on the the existance of a data source,
* you may use this command in a setup project. Read more about setup projects
* here: https://playwright.dev/docs/auth#basic-shared-account-in-all-tests
Copy link
Collaborator

@leventebalogh leventebalogh Nov 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea: I think this comment is ok as it is and already really useful, however maybe in the future we could add some Grafana-related examples which we could link to from here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 100%! Actually this comment was made before I knew that it's possible to use env variables in provisioning files. That kind of makes this comment obsolete. I'll change it. But we should definitely have examples of using provisioning with (and without) secrets in plugin-examples eventually.

await this.ctx.page
.getByLabel(this.ctx.selectors.components.PanelEditor.General.content)
.locator(`selector=${this.ctx.selectors.components.TimePicker.openButton}`)
.click({ force: true, timeout: 2000 });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the 2000ms timeout here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question...this is mostly copied from plugin/e2e in grafana core. I'll remove it and we'll see. If timeout is not provided explicitly like in this case, timeout from playwright config will be used. It defaults to 5000ms if I recall correctly. Will changed this!

.click({ force: true, timeout: 2000 });
} catch (e) {
// seems like in older versions of Grafana the time picker markup is rendered twice
await this.ctx.page.locator('[aria-controls="TimePickerContent"]').last().click();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be that the error is caused by something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlikely, but maybe. Anyway, I don't like this so I'll add a todo for finding a better solution for this. Have a bunch of todos throughout the code...most of them involves changes in Grafana ui so would like to collect a few before I get to them.

@@ -11,6 +11,6 @@ test('valid credentials should return a 200 status code', async ({ createDataSou
const configPage = await createDataSourceConfigPage({ type: 'grafana-googlesheets-datasource' });
await page.getByText('Google JWT File', { exact: true }).click();
await page.getByTestId('Paste JWT button').click();
await page.getByTestId('Configuration text area').fill(process.env.GOOGLE_JWT_FILE!);
await page.getByTestId('Configuration text area').fill(process.env.GOOGLE_JWT_FILE!.replace(/'/g, ''));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity, why do we need to remove the ' single quotes here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is also used here in the provisioning file for google sheets. Seems like the jwt file needs to be wrapped in single quotes for provisioning to work, so that's how the GH secret is defined. That however doesn't work when creating a new sheets ds using the UI, so therefore I'm removing the single quotes.


await panelEditPage.refreshPanel();
await expect(await queryReq).toBeTruthy();
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the "semantic" difference between the tests in queryEditor.integration.spec.ts and queryEditor.spec.ts? In other words, how do we suggest to organise tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good question!

queryEditor.spec.ts just tests the query editor. I.e checking the right endpoints are being called when a certain button is clicked and so on. I want to test the query editor in isolation, so any backend endpoints are mocked.

queryEditor.integration.spec.ts is calling the downstream sheets API and fetches data from a readonly spreadsheet.

Ultimately, it will be up to the plugin author to decide what kind of tests they want to have. Both may be useful. Hitting real downstream APIs can be very useful, but it may come with security concerns and also cause flakiness.

@@ -1,7 +1,8 @@
{
"compilerOptions": {
"outDir": "./dist",
"declaration": true
"declaration": true,
"stripInternal": true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity - how do we decide which types should be private and which ones should be public? I sometimes find it useful during development to have access to as many types as possible when working with a package, while on the other hand it can tie our hands if we expose too much, as we can hardly change what a lot of people depend on.

sunker and others added 4 commits November 24, 2023 15:40
Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com>
Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com>
Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com>
@sunker
Copy link
Contributor Author

sunker commented Nov 24, 2023

Thanks for good feedback @leventebalogh!

@sunker sunker merged commit 33000d1 into main Nov 24, 2023
18 checks passed
@sunker sunker deleted the query-editor branch November 24, 2023 18:35
@sunker sunker mentioned this pull request Dec 11, 2023
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-changelog Don't include in changelog and version calculations
Projects
Development

Successfully merging this pull request may close these issues.

2 participants