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: [M3-8133] - Add Cypress test for Login History page #10575

Merged
merged 4 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-10575-tests-1720464616116.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Add Cypress test for Login History page ([#10575](https://github.com/linode/manager/pull/10575))
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { accountLoginFactory } from 'src/factories/accountLogin';
import { formatDate } from 'src/utilities/formatDate';
import { mockGetAccountLogins } from 'support/intercepts/account';
import { mockGetProfile } from 'support/intercepts/profile';
import {
loginHelperText,
loginEmptyStateMessageText,
} from 'support/constants/account';
import { PARENT_USER } from 'src/features/Account/constants';

describe('Account login history', () => {
Expand Down Expand Up @@ -42,9 +46,7 @@ describe('Account login history', () => {
cy.wait(['@getProfile']);

// Confirm helper text above table is visible.
cy.findByText(
'Logins across all users on your account over the last 90 days.'
).should('be.visible');
cy.findByText(loginHelperText).should('be.visible');

// Confirm the login table includes the expected column headers and mocked logins are visible in table.
cy.findByLabelText('Account Logins').within(() => {
Expand Down Expand Up @@ -72,9 +74,6 @@ describe('Account login history', () => {
.closest('tr')
.within(() => {
// Confirm that successful login and status icon display in table.
cy.findByText(mockSuccessfulLogin.status, { exact: false }).should(
'be.visible'
);
cy.findAllByLabelText(`Status is ${mockSuccessfulLogin.status}`);

// Confirm all other fields display in table.
Expand Down Expand Up @@ -108,9 +107,7 @@ describe('Account login history', () => {
cy.wait(['@getProfile']);

// Confirm helper text above table and table are not visible.
cy.findByText(
'Logins across all users on your account over the last 90 days.'
).should('not.exist');
cy.findByText(loginHelperText).should('not.exist');
cy.findByLabelText('Account Logins').should('not.exist');

cy.findByText(
Expand All @@ -137,13 +134,114 @@ describe('Account login history', () => {
cy.wait(['@getProfile']);

// Confirm helper text above table and table are not visible.
cy.findByText(
'Logins across all users on your account over the last 90 days.'
).should('not.exist');
cy.findByText(loginHelperText).should('not.exist');
cy.findByLabelText('Account Logins').should('not.exist');

cy.findByText(
"You don't have permissions to edit this Account. Please contact your account administrator to request the necessary permissions."
);
});

/*
* - Vaildates login history landing page with mock data.
* - Confirms that each login is listed in the Login History table.
* - Confirms that "Successful" indicator is shown for successful login attempts, and the "Failure" indicator is shown for the failed ones.
* - Confirms that clicking on the username for the login navigates to the expected user page
*/
it('shows each login in the Login History landing page as expected', () => {
const mockProfile = profileFactory.build({
username: 'mock-user',
restricted: false,
user_type: 'default',
});
const mockFailedLogin = accountLoginFactory.build({
status: 'failed',
username: 'mock-user-failed',
restricted: false,
});
const mockSuccessfulLogin = accountLoginFactory.build({
status: 'successful',
username: 'mock-user-successful',
restricted: false,
});

mockGetProfile(mockProfile).as('getProfile');
mockGetAccountLogins([mockFailedLogin, mockSuccessfulLogin]).as(
'getAccountLogins'
);

// Navigate to Account Login History page.
cy.visitWithLogin('/account/login-history');
cy.wait(['@getProfile']);

// Confirm helper text above table is visible.
cy.findByText(loginHelperText).should('be.visible');

// Confirm the login table includes the expected column headers and mocked logins are visible in table.
cy.findByLabelText('Account Logins').within(() => {
cy.get('thead').findByText('Date').should('be.visible');
cy.get('thead').findByText('Username').should('be.visible');
cy.get('thead').findByText('IP').should('be.visible');
cy.get('thead').findByText('Permission Level').should('be.visible');
cy.get('thead').findByText('Access').should('be.visible');

// Confirm that restricted user's failed login and status icon display in table.
cy.findByText(mockFailedLogin.username)
.should('be.visible')
.closest('tr')
.within(() => {
// cy.findByText(mockFailedLogin.status, { exact: false }).should(
// 'be.visible'
// );
cy.findAllByLabelText(`Status is ${mockFailedLogin.status}`);
cy.findByText('Unrestricted').should('be.visible');
});

// Confirm that unrestricted user login displays in table.
cy.findByText(mockSuccessfulLogin.username)
.should('be.visible')
.closest('tr')
.within(() => {
// Confirm that successful login and status icon display in table.
cy.findAllByLabelText(`Status is ${mockSuccessfulLogin.status}`);

// Confirm all other fields display in table.
cy.findByText(
formatDate(mockSuccessfulLogin.datetime, {
timezone: mockProfile.timezone,
})
).should('be.visible');
cy.findByText(mockSuccessfulLogin.ip).should('be.visible');
cy.findByText('Unrestricted').should('be.visible');
});
});
});

/*
* - Confirms that empty state is handled gracefully, showing corresponding message.
*/
it('shows empty message when there is no login history', () => {
mockGetAccountLogins([]).as('getAccountLogins');

// Navigate to Login History landing page.
cy.visitWithLogin('/account/login-history');
cy.wait('@getAccountLogins');

// Confirm helper text above table is visible.
cy.findByText(loginHelperText).should('be.visible');

cy.findByLabelText('Account Logins').within(() => {
cy.get('thead').findByText('Date').should('be.visible');
cy.get('thead').findByText('Username').should('be.visible');
cy.get('thead').findByText('IP').should('be.visible');
cy.get('thead').findByText('Permission Level').should('be.visible');
cy.get('thead').findByText('Access').should('be.visible');
});

cy.get('[data-testid="table-row-empty"]')
.should('be.visible')
.within(() => {
cy.findByText(loginEmptyStateMessageText).should('be.visible');
});
});
});
11 changes: 11 additions & 0 deletions packages/manager/cypress/support/constants/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ We cannot cancel this account until the balance has been paid.';
*/
export const sshFormatErrorMessage =
'SSH Key key-type must be ssh-dss, ssh-rsa, ecdsa-sha2-nistp, ssh-ed25519, or sk-ecdsa-sha2-nistp256.';

/**
* Helper text that appears above the login history table.
*/
export const loginHelperText =
'Logins across all users on your account over the last 90 days.';

/**
* Empty state message that appears when there is no item in the login history table.
*/
export const loginEmptyStateMessageText = 'No account logins';
Comment on lines +21 to +31
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for these!

Loading