-
Notifications
You must be signed in to change notification settings - Fork 178
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
[RHOAIENG-1154]: Apply modal to alert user error #3512
base: main
Are you sure you want to change the base?
Conversation
2dc38bb
to
d33ca1c
Compare
Would there be a way to detect specifically that the user's session timed out to show the new modal? I feel like it may be slightly misleading because it looks like the code is a catch all, but the message is specific for session expiration? Unless that was the idea, it also doesn't seem that straightfoward to figure out a expired session |
I agree, we should look to identify the exact error response that comes from an expired session to show this modal otherwise we show the old error or update it with some other text if it's not related to expired session. |
Thanks @jenny-s51. The implementation looks good to me. |
d33ca1c
to
cd37c9c
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
39e8c1e
to
3c6f22e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your feedback here @emilys314 @christianvogt @xianli123 - after investigating with @christianvogt we identified that a 403 status code indicates an expired session.
I've updated the implementation to render the modal when that status code is received, and added a corresponding Cypress test.
d26db87
to
07e11ba
Compare
export class LoginDialog { | ||
findText(): Chainable<JQuery<HTMLElement>> { | ||
return cy.findByTestId('timeout-text'); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For modals we normally create a contextual page object which extends the Modal
class:
export class LoginDialog { | |
findText(): Chainable<JQuery<HTMLElement>> { | |
return cy.findByTestId('timeout-text'); | |
} | |
} | |
class LoginDialog extends Modal { | |
constructor() { | |
super('Session Expired'); | |
} | |
} |
With a new instance of this class you can then do loginDialog().shouldBeOpen()
instead of the modal text assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied this change with loginDialog.shouldBeOpen()
- the test isn't passing though because the find()
call in shouldBeOpen
doesn't identify this modal correctly. Investigating...
frontend/src/app/App.tsx
Outdated
<Modal variant={ModalVariant.small} isOpen ouiaId="BasicModal"> | ||
<ModalHeader title="Session Expired" titleIconVariant="warning" /> | ||
<ModalBody data-testid="timeout-text"> | ||
Your session timed out. To continue working, log in. | ||
</ModalBody> | ||
<ModalFooter> | ||
<Button | ||
key="confirm" | ||
variant="primary" | ||
onClick={() => logout().then(() => window.location.reload())} | ||
> | ||
Log in | ||
</Button> | ||
</ModalFooter> | ||
</Modal> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this Modal to a separate file for better separation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks, created a separate component for this.
@@ -113,4 +114,22 @@ describe('Application', () => { | |||
aboutDialog.findText().should('contain.text', 'OpenShift'); | |||
aboutDialog.findProductName().should('contain.text', 'OpenShift AI'); | |||
}); | |||
it('should show the login modal when receiving a 403 status code', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test can also intercept the call to /oauth/sign_out
when the user clicks the Log in
button.
3339be0
to
020337d
Compare
class LoginDialog extends Modal { | ||
protected testId; | ||
|
||
constructor(title: string, testId: string) { | ||
super(title); | ||
this.testId = testId; | ||
} | ||
|
||
find() { | ||
return cy.findByTestId(this.testId); | ||
} | ||
|
||
findLoginButton() { | ||
return this.findFooter().findByTestId('modal-login-button'); | ||
} | ||
} | ||
|
||
export const loginDialog = new LoginDialog('Session Expired', 'session-expired-modal'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to parameterize the constructor since you're not going to instantiate different login dialogs:
class LoginDialog extends Modal { | |
protected testId; | |
constructor(title: string, testId: string) { | |
super(title); | |
this.testId = testId; | |
} | |
find() { | |
return cy.findByTestId(this.testId); | |
} | |
findLoginButton() { | |
return this.findFooter().findByTestId('modal-login-button'); | |
} | |
} | |
export const loginDialog = new LoginDialog('Session Expired', 'session-expired-modal'); | |
class LoginDialog extends Modal { | |
constructor() { | |
super('Session Expired'); | |
} | |
find() { | |
return cy.findByTestId('session-expired-modal'); | |
} | |
findLoginButton() { | |
return this.findFooter().findByTestId('modal-login-button'); | |
} | |
} | |
export const loginDialog = new LoginDialog(); |
}).as('getData403'); | ||
|
||
// Set up the sign-out intercept before visiting the page | ||
cy.intercept('GET', '/oauth/sign_out').as('signOut'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to add a typed interface function to the interceptOdh
method. We tend to do this for all our well known URLs.
f61696f
to
23fb1b1
Compare
check for 403 status code add cypress test update test title format format format remove it.only fix relative import PR feedback from Christian, WIP Cypress throwing error on shouldBeOpen fix tests, fix linting issues revert find() function revert find, update comment format apply PR comments from review format remove response param uncomment simulate login button remove it.only reorder
23fb1b1
to
ab7ef3f
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3512 +/- ##
==========================================
+ Coverage 85.01% 85.04% +0.02%
==========================================
Files 1404 1405 +1
Lines 32244 32247 +3
Branches 9042 9044 +2
==========================================
+ Hits 27412 27424 +12
+ Misses 4832 4823 -9
... and 3 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
Towards https://issues.redhat.com/browse/RHOAIENG-1154.
Description
Before:
After:
How Has This Been Tested?
Run
application.cy.ts
to simulate 403 status code and verify the modal is rendered.Test Impact
Added new test to
application.cy.ts
.Request review criteria:
Self checklist (all need to be checked):
If you have UI changes:
After the PR is posted & before it merges:
main