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

test: Jcom/infeng 454/sign in tests #9013

Merged
merged 47 commits into from
Mar 25, 2024
Merged

Conversation

JComins000
Copy link
Contributor

@JComins000 JComins000 commented Mar 16, 2024

INFENG-454

Description

adds page models for sign in tests
add a new test for when we sign in with wrong creds
add test hooks into a few react components

Test Plan

the tests run on CI

Commentary (optional)

Checklist

  • Changes have been manually QA'd
  • User-facing API changes need the "User-facing API Change" label.
  • Release notes should be added as a separate file under docs/release-notes/.
    See Release Note for details.
  • Licenses should be included for new code which was copied and/or modified from any external code.

Ticket

INFENG-454

@cla-bot cla-bot bot added the cla-signed label Mar 16, 2024
Copy link

netlify bot commented Mar 16, 2024

Deploy Preview for determined-ui ready!

Name Link
🔨 Latest commit cf71f65
🔍 Latest deploy log https://app.netlify.com/sites/determined-ui/deploys/6601f09d9d3a6f00082727ee
😎 Deploy Preview https://deploy-preview-9013--determined-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@JComins000 JComins000 force-pushed the jcom/INFENG-454/sign-in-tests branch from 54a0a8e to d1252b7 Compare March 19, 2024 23:23
@JComins000 JComins000 force-pushed the jcom/INFENG-454/sign-in-tests branch from d1252b7 to f0e6b67 Compare March 19, 2024 23:26
@djanicekpach djanicekpach self-requested a review March 20, 2024 15:00
@@ -87,6 +87,7 @@ const DeterminedAuth: React.FC<Props> = ({ canceler }: Props) => {

const loginForm = (
<Form
data-test="authForm"
Copy link
Contributor

Choose a reason for hiding this comment

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

spelling: data-testid I think you mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually, i like top level components to have data-test. when the form gets implemented in SignIn.tsx, sign in could give it a data-testid, but it wouldn't need to unless it was instantiating more than one of this component. I'll write this up in a guide somewhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you like top level components to be slightly different? To me it reads like an extra style thing for maintainers to remember and no implied meaning.
If you do want the top level to be different, can it be explicit? Something like data-top-level-testid or data-formid? It'd be good if the name was different enough to indicate that this difference is intentional, and ideally it could also describe why it was different.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

maybe this?

data-test-component='my-component'

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems diffferent enough form data-testid to avoid confusion. works for me!

webui/react/src/components/DeterminedAuth.tsx Show resolved Hide resolved
placeholder="password"
prefix={<Icon name="lock" size="small" title="Password" />}
/>
</Form.Item>
{isBadCredentials && (
<p className={[css.errorMessage, css.message].join(' ')}>Incorrect username or password.</p>
<p className={[css.errorMessage, css.message].join(' ')} data-testid="error">Incorrect username or password.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: maybe bad-cred-error or something in case there is ever more than one on the page?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there actually are two alerts since there's almost always one in the bottom right. I'd like to have a list of errors. Maybe a BaseComponents plural class?

Copy link
Contributor

Choose a reason for hiding this comment

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

A list of errors would be nice. Feel free to punt to out of scope and make a follow up ticke here though since it sounds like that might be more involved. I don't love plural classes in languages with generic types. We can just do a Array and get most of the functionality for a lot less code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually, this isn't even the notification that shows in our test. im gonna delete this change

throw new Error('username must be defined')
}
if (typeof process.env.PW_PASSWORD === "undefined") {
throw new Error('username must be defined')
Copy link
Contributor

Choose a reason for hiding this comment

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

copy&paste: password instead of username.

webui/react/src/e2e/models/BaseComponent.ts Outdated Show resolved Hide resolved
webui/react/src/e2e/models/BaseComponent.ts Outdated Show resolved Hide resolved
get locateSelf(): Locator {
if (typeof this._locator === 'undefined') {
this._locator = this._parent.pwLocatorFunction(this.#selector);
Object.freeze(this._locator)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we freezing the object here? It makes me a little nervous. Hopefully playwright doesn't keep any mutable data on Locator classes under the hood!

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 wanted the attribute to only be instantiated once. it's kind of like saying

const myLocator = page.locator('my_selector')

I didn't want to create the "const" until we started using it. it behaves like a readonly that we're allowed to write to once.

Copy link
Contributor

Choose a reason for hiding this comment

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

Object.freeze is a bit different than const or readonly. It prevents reassignment, but also prevents changing the properties of the underlying object. If playwright ever alters a property under the hood (it's their object so that's pretty reasonable) it could cause a crash.

I love having constants instead of variables, but for a protected variable with a public getter, I think the benefits of this lockdown are kind of minimal when compared to the potential consequences. If you really want to protect it you could make a setter and either declare it private, or throw an error when it gets set and already has a value.

export class SignIn extends BasePage {
readonly pageComponent: PageComponent = new PageComponent({parent: this});
readonly detAuth: DeterminedAuth = new DeterminedAuth({parent: this.pageComponent})
// TODO add SSO page model as well
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems probably out of scope, so feel free to make a ticket for sso. I think a lot more setup has to go into it.

get locateSelf(): Locator {
if (typeof this._locator === 'undefined') {
this._locator = this._parent.pwLocatorFunction(this.#selector);
Object.freeze(this._locator)
Copy link
Contributor

Choose a reason for hiding this comment

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

Object.freeze is a bit different than const or readonly. It prevents reassignment, but also prevents changing the properties of the underlying object. If playwright ever alters a property under the hood (it's their object so that's pretty reasonable) it could cause a crash.

I love having constants instead of variables, but for a protected variable with a public getter, I think the benefits of this lockdown are kind of minimal when compared to the potential consequences. If you really want to protect it you could make a setter and either declare it private, or throw an error when it gets set and already has a value.

@@ -87,6 +87,7 @@ const DeterminedAuth: React.FC<Props> = ({ canceler }: Props) => {

const loginForm = (
<Form
data-test="authForm"
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you like top level components to be slightly different? To me it reads like an extra style thing for maintainers to remember and no implied meaning.
If you do want the top level to be different, can it be explicit? Something like data-top-level-testid or data-formid? It'd be good if the name was different enough to indicate that this difference is intentional, and ideally it could also describe why it was different.

placeholder="password"
prefix={<Icon name="lock" size="small" title="Password" />}
/>
</Form.Item>
{isBadCredentials && (
<p className={[css.errorMessage, css.message].join(' ')}>Incorrect username or password.</p>
<p className={[css.errorMessage, css.message].join(' ')} data-testid="error">Incorrect username or password.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

A list of errors would be nice. Feel free to punt to out of scope and make a follow up ticke here though since it sounds like that might be more involved. I don't love plural classes in languages with generic types. We can just do a Array and get most of the functionality for a lot less code.

@JComins000 JComins000 marked this pull request as ready for review March 22, 2024 19:26
@JComins000 JComins000 requested a review from a team as a code owner March 22, 2024 19:26
@JComins000 JComins000 requested a review from ashtonG March 22, 2024 19:26
@@ -17,7 +17,7 @@ export default defineConfig({
fullyParallel: !!process.env.CI,

/* https://playwright.dev/docs/test-timeouts#global-timeout */
globalTimeout: 3 * 60 * 1000, // 3 min
globalTimeout: process.env.PWDEBUG ? 0 : 3 * 60 * 1000, // 3 min unless debugging
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! I was thinking about doing this and forgot.

webui/react/src/e2e/fixtures/auth.fixture.ts Outdated Show resolved Hide resolved
Copy link

codecov bot commented Mar 25, 2024

Codecov Report

Attention: Patch coverage is 0% with 258 lines in your changes are missing coverage. Please review.

Project coverage is 41.63%. Comparing base (e4bc377) to head (cf71f65).
Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9013      +/-   ##
==========================================
- Coverage   47.80%   41.63%   -6.18%     
==========================================
  Files        1161      847     -314     
  Lines      143646   104428   -39218     
  Branches     2373     2377       +4     
==========================================
- Hits        68673    43475   -25198     
+ Misses      74820    60794   -14026     
- Partials      153      159       +6     
Flag Coverage Δ
harness ?
web 40.74% <0.00%> (-0.17%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
webui/react/src/components/DeterminedAuth.tsx 0.00% <0.00%> (ø)
webui/react/src/e2e/models/components/Page.ts 0.00% <0.00%> (ø)
webui/react/src/e2e/models/pages/SignIn.ts 0.00% <0.00%> (ø)
webui/react/src/e2e/models/utils/error.ts 0.00% <0.00%> (ø)
webui/react/src/e2e/fixtures/auth.fixture.ts 0.00% <0.00%> (ø)
webui/react/src/e2e/models/BasePage.ts 0.00% <0.00%> (ø)
.../react/src/e2e/models/components/DeterminedAuth.ts 0.00% <0.00%> (ø)
webui/react/src/e2e/models/BaseComponent.ts 0.00% <0.00%> (ø)

... and 320 files with indirect coverage changes

@JComins000 JComins000 merged commit 60cb003 into main Mar 25, 2024
69 of 81 checks passed
@JComins000 JComins000 deleted the jcom/INFENG-454/sign-in-tests branch March 25, 2024 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants