Skip to content
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-12936-tests-1759312166894.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Add Logs Destination Landing, Create and Edit e2e tests ([#12936](https://github.com/linode/manager/pull/12936))
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import {
mockDestination,
mockDestinationPayload,
} from 'support/constants/delivery';
import {
mockCreateDestination,
mockGetDestinations,
mockTestConnection,
} from 'support/intercepts/delivery';
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { ui } from 'support/ui';
import { logsDestinationForm } from 'support/ui/pages/logs-destination-form';

import type { AkamaiObjectStorageDetails } from '@linode/api-v4';

describe('Create Destination', () => {

Check warning on line 16 in packages/manager/cypress/e2e/core/delivery/create-destination.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 5 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 5 times.","line":16,"column":10,"nodeType":"Literal","endLine":16,"endColumn":30}
before(() => {
mockAppendFeatureFlags({
aclpLogs: { enabled: true, beta: true },
});
});

it('create destination with form', () => {
cy.visitWithLogin('/logs/delivery/destinations/create');

// Give Destination a label
logsDestinationForm.setLabel(mockDestinationPayload.label);

logsDestinationForm.fillDestinationDetailsForm(
mockDestinationPayload.details as AkamaiObjectStorageDetails
);

// Create Destination should be disabled before test connection
cy.findByRole('button', { name: 'Create Destination' }).should(
'be.disabled'
);

// Test connection of the destination form - failure
mockTestConnection(400);
ui.button
.findByTitle('Test Connection')
.should('be.enabled')

Check warning on line 42 in packages/manager/cypress/e2e/core/delivery/create-destination.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 4 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 4 times.","line":42,"column":15,"nodeType":"Literal","endLine":42,"endColumn":27}
.should('have.attr', 'type', 'button')
.click();

ui.toast.assertMessage(
'Delivery connection test failed. Verify your delivery settings and try again.'
);

// Create Destination should be disabled after test connection failed
cy.findByRole('button', { name: 'Create Destination' }).should(
'be.disabled'
);

// Test connection of the destination form - success
mockTestConnection(200);
ui.button
.findByTitle('Test Connection')
.should('be.enabled')
.should('have.attr', 'type', 'button')
.click();

ui.toast.assertMessage(
`Delivery connection test completed successfully. Data can now be sent using this configuration.`
);

// Submit the destination create form - failure
mockCreateDestination({}, 400);
cy.findByRole('button', { name: 'Create Destination' })
.should('be.enabled')
.should('have.attr', 'type', 'button')
.click();

ui.toast.assertMessage(`There was an issue creating your destination`);

// Submit the destination create form - success
mockCreateDestination(mockDestination);
mockGetDestinations([mockDestination]);
cy.findByRole('button', { name: 'Create Destination' })
.should('be.enabled')
.should('have.attr', 'type', 'button')
.click();

ui.toast.assertMessage(
`Destination ${mockDestination.label} created successfully`
);

// Verify we redirect to the destinations landing page upon successful creation
cy.url().should('endWith', 'destinations');

// Verify the newly created destination shows on the Destinations landing page
cy.findByText(mockDestination.label)
.closest('tr')
.within(() => {
// Verify Destination label shows
cy.findByText(mockDestination.label).should('be.visible');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { mockGetDestinations } from 'support/intercepts/delivery';
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { ui } from 'support/ui';

describe('Destinations empty landing page', () => {
beforeEach(() => {
mockAppendFeatureFlags({
aclpLogs: {
enabled: true,
beta: true,
},
});
});

/**
* - Confirms Destinations landing page empty state is shown when no Destinations are present:
* - Confirms that clicking "Create Destination" navigates user to create destination page.
*/
it('shows the empty state when there are no destinations', () => {
mockGetDestinations([]).as('getDestinations');

cy.visitWithLogin('/logs/delivery/destinations');
cy.wait(['@getDestinations']);

// Confirm empty Destinations Landing Text
cy.findByText('Create a destination for cloud logs').should('be.visible');

// confirms clicking on 'Create Domain' button
ui.button
.findByTitle('Create Destination')
.should('be.visible')
.should('be.enabled')
.click();

cy.url().should('endWith', '/logs/delivery/destinations/create');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import {
interceptDeleteDestination,
mockDeleteDestination,
mockGetDestination,
mockGetDestinations,
} from 'support/intercepts/delivery';
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { ui } from 'support/ui';

import { destinationFactory } from 'src/factories';

import type { Destination } from '@linode/api-v4';

function checkActionMenu(tableAlias: string, mockDestinations: Destination[]) {
mockDestinations.forEach((destination) => {
cy.get(tableAlias)
.find('tbody tr')
.should('contain', destination.label)
.then(() => {
// If the row contains the label, proceed with clicking the action menu
ui.actionMenu
.findByTitle(`Action menu for Destination ${destination.label}`)
.should('be.visible')

Check warning on line 23 in packages/manager/cypress/e2e/core/delivery/destinations-non-empty-landing-page.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 6 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 6 times.","line":23,"column":19,"nodeType":"Literal","endLine":23,"endColumn":31}
.click();

// Check that all items are enabled
ui.actionMenuItem
.findByTitle('Edit')
.should('be.visible')
.should('be.enabled');

Check warning on line 30 in packages/manager/cypress/e2e/core/delivery/destinations-non-empty-landing-page.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":30,"column":19,"nodeType":"Literal","endLine":30,"endColumn":31}

ui.actionMenuItem
.findByTitle('Delete')
.should('be.visible')
.should('be.enabled');
});

// Close the action menu by clicking on Delivery Title of the screen
cy.get('body').click(0, 0);
});
}

function deleteItem(tableAlias: string, destination: Destination) {
cy.get(tableAlias)
.find('tbody tr')
.should('contain', destination.label)
.then(() => {
// If the row contains the label, proceed with clicking the action menu
ui.actionMenu
.findByTitle(`Action menu for Destination ${destination.label}`)
.should('be.visible')
.click();

mockDeleteDestination(404); // @TODO remove after API release on prod

Check warning on line 54 in packages/manager/cypress/e2e/core/delivery/destinations-non-empty-landing-page.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Complete the task associated to this "TODO" comment. Raw Output: {"ruleId":"sonarjs/todo-tag","severity":1,"message":"Complete the task associated to this \"TODO\" comment.","line":54,"column":39,"nodeType":null,"messageId":"completeTODO","endLine":54,"endColumn":43}
interceptDeleteDestination().as('deleteDestination');

// Delete destination
ui.actionMenuItem.findByTitle('Delete').click();

// Find confirmation modal
cy.findByText(
`Are you sure you want to delete "${destination.label}" destination?`
);
ui.button.findByTitle('Delete').click();

cy.wait('@deleteDestination');

// Close confirmation modal after failure
ui.button.findByTitle('Cancel').click();
});
}

function editItemViaActionMenu(tableAlias: string, destination: Destination) {
cy.get(tableAlias)
.find('tbody tr')
.should('contain', destination.label)
.then(() => {
// If the row contains the label, proceed with clicking the action menu
ui.actionMenu
.findByTitle(`Action menu for Destination ${destination.label}`)
.should('be.visible')
.click();

mockGetDestination(destination);
// Edit destination redirect
ui.actionMenuItem.findByTitle('Edit').click();
cy.url().should('endWith', `/destinations/${destination.id}/edit`);
});
}

const mockDestinations: Destination[] = new Array(3)
.fill(null)
.map((_item: null, index: number): Destination => {
return destinationFactory.build({
label: `Destination ${index}`,
});
});

describe('destinations landing checks for non-empty state', () => {
beforeEach(() => {
mockAppendFeatureFlags({
aclpLogs: { enabled: true, beta: true },
});

// Mock setup to display the Destinations landing page in a non-empty state
mockGetDestinations(mockDestinations).as('getDestinations');

// Alias the mockDestinations array
cy.wrap(mockDestinations).as('mockDestinations');
});

it('checks create destination button is enabled and user can see existing destinations', () => {
// Login and wait for application to load
cy.visitWithLogin('/logs/delivery/destinations');

Check warning on line 114 in packages/manager/cypress/e2e/core/delivery/destinations-non-empty-landing-page.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":114,"column":23,"nodeType":"Literal","endLine":114,"endColumn":52}
cy.wait('@getDestinations');

Check warning on line 115 in packages/manager/cypress/e2e/core/delivery/destinations-non-empty-landing-page.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":115,"column":13,"nodeType":"Literal","endLine":115,"endColumn":31}
cy.url().should('endWith', '/destinations');

cy.get('table').should('exist').as('destinationsTable');

// Assert that Create Destination button is visible and enabled
ui.button
.findByTitle('Create Destination')
.should('be.visible')
.and('be.enabled');

// Assert that the correct number of Destinations entries are present in the DestinationsTable
cy.get('@destinationsTable')

Check warning on line 127 in packages/manager/cypress/e2e/core/delivery/destinations-non-empty-landing-page.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 4 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 4 times.","line":127,"column":12,"nodeType":"Literal","endLine":127,"endColumn":32}
.find('tbody tr')
.should('have.length', mockDestinations.length);

checkActionMenu('@destinationsTable', mockDestinations); // For the recovery destination table
});

it('checks actions from destination menu actions', () => {
cy.visitWithLogin('/logs/delivery/destinations');
cy.wait('@getDestinations');
cy.get('table').should('exist').as('destinationsTable');

const exampleDestination = mockDestinations[0];
deleteItem('@destinationsTable', exampleDestination);

mockGetDestination(exampleDestination).as('getDestination');

// Redirect to destination edit page via name
cy.findByText(exampleDestination.label).click();
cy.url().should('endWith', `/destinations/${exampleDestination.id}/edit`);
cy.wait('@getDestination');

cy.visit('/logs/delivery/destinations');
cy.get('table').should('exist').as('destinationsTable');
cy.wait('@getDestinations');
editItemViaActionMenu('@destinationsTable', exampleDestination);
});
});
Loading
Loading