Skip to content

chore: add e2e test against an external auth provider during workspace creation #12985

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

Merged
merged 4 commits into from
Apr 18, 2024

Conversation

dannykopping
Copy link
Contributor

Closes #12585

Signed-off-by: Danny Kopping <danny@coder.com>
Signed-off-by: Danny Kopping <danny@coder.com>
@dannykopping dannykopping requested review from Parkreiner and mtojek and removed request for Parkreiner April 17, 2024 09:36
@dannykopping dannykopping changed the title chore: add e2e test for authenticating against an external auth provider during workspace creation chore: add e2e test against an external auth provider during workspace creation Apr 17, 2024
Copy link
Member

@mtojek mtojek left a comment

Choose a reason for hiding this comment

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

A simple mock looks like a decent solution 👍 Anyway, CI seems to be still failing.

@@ -27,6 +27,7 @@ export const ExternalAuthButton: FC<ExternalAuthButtonProps> = ({
<>
<div css={{ display: "flex", alignItems: "center", gap: 8 }}>
<LoadingButton
id={"external-auth-" + auth.id}
Copy link
Member

Choose a reason for hiding this comment

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

if this is just for testing purposes, then probably data-testid.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, IDs are mainly supposed to be used for associating HTML elements with other elements, or associating elements with browser URL state

I want to say that if you need some kind of "ID-like value"/testing hook for your elements, and the value doesn't have any functionality for the end-user, data attributes (like data-testid) are the way to go

Copy link
Member

Choose a reason for hiding this comment

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

Another concern is that HTML IDs have to be globally unique. If multiple HTML elements have the same ID, that can cause some nasty jank (e.g., clicking a form input, and a different input getting highlighted)

React has a built-in hook for making it easy to have unique IDs, even when you're working with reusable components
https://react.dev/reference/react/useId

@dannykopping
Copy link
Contributor Author

dannykopping commented Apr 17, 2024

CI seems to be still failing.

Hhmm yeah seems like the server is already running (I just copied some code from another test for the server):
Error: listen EADDRINUSE: address already in use 0.0.0.0:50516.

I guess it's not shutdown once the test completes...?

Copy link
Member

@Parkreiner Parkreiner left a comment

Choose a reason for hiding this comment

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

Had a couple of comments on how some of the functions were set up, but I think this looks good overall

As long as getting the test to pass won't dramatically change the code, I can approve this

Comment on lines 70 to 72
const externalAuthLoginButton = page.locator(
"#external-auth-" + useExternalAuthProvider,
);
Copy link
Member

Choose a reason for hiding this comment

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

Regardless of the main way we end up selecting the element, I would recommend making sure the selector asserts that the element we're grabbing is actually exposed to the user as a button (ideally through something like page.getByRole)

It's possible to add click behavior to non-button elements, but that can get janky quick. Changing the selector would add an extra security net to ensure that users can use all the behavior that buttons bake in automatically

Comment on lines 50 to +53
templateName: string,
richParameters: RichParameter[] = [],
buildParameters: WorkspaceBuildParameter[] = [],
useExternalAuthProvider: string | undefined = undefined,
Copy link
Member

Choose a reason for hiding this comment

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

I think that with the new parameter, the function is getting a little unwieldy, and if you're looking at things from the consumer side, it's hard to tell which of the five arguments correspond to what

Maybe this could be refactored to an object, so that we have sort of have named arguments?

type CreateWorkspaceInputs = Readonly<{
  // Required properties
  page: Page;
  templateName: string;
  
  // Optional properties
  richParameters?: readonly RichParameter[];
  buildParameters?: readonly WorkspaceBuildParameter[];
  externalAuthProvider?: string;
}>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree in principle, but I think 5 params is still manageable and not worth refactoring the 26 usages of this function IMHO. Happy to discuss.

@mtojek
Copy link
Member

mtojek commented Apr 18, 2024

I guess it's not shutdown once the test completes...?

This or maybe tests are just running in parallel

@dannykopping
Copy link
Contributor Author

I guess it's not shutdown once the test completes...?

This or maybe tests are just running in parallel

AFAICS they seem to run serially.
I chased this down a little yesterday and found that there's also a shared state issue between tests; the auth tokens are persistent across test runs, so the "Login with ..." button is replaced with "Authenticated with ..." since there is a valid token. I'm looking into clearing the db state between runs.

…st to reauthenticate

Signed-off-by: Danny Kopping <danny@coder.com>
Signed-off-by: Danny Kopping <danny@coder.com>
@dannykopping
Copy link
Contributor Author

dannykopping commented Apr 18, 2024

Wow, OK. That was a bit tricky...

When external auth web ran, it'd create a valid external auth link such that when successful external auth from workspace ran subsequently, the Login with GitHub button was inactive because the session was already authenticated; this kind of leakage between tests is not ideal.

I needed to delete the external auth link between the session & the oauth token to force each test to authenticate afresh. Additionally I had to make the mock oauth server start before all the tests rather than creating one per test.

@mtojek @Parkreiner would you mind taking another look? I've addressed the other review comments, too.

@mtojek mtojek self-requested a review April 18, 2024 14:03
Copy link
Member

@mtojek mtojek left a comment

Choose a reason for hiding this comment

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

Nice job 👍!

@dannykopping dannykopping merged commit 319fd5b into coder:main Apr 18, 2024
26 checks passed
@dannykopping dannykopping deleted the dk/e2eea branch April 18, 2024 17:43
@github-actions github-actions bot locked and limited conversation to collaborators Apr 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

e2e: test authenticating with external auth when creating workspace
3 participants