diff --git a/packages/manager/.changeset/pr-10403-tests-1714588716317.md b/packages/manager/.changeset/pr-10403-tests-1714588716317.md new file mode 100644 index 00000000000..bb82b13608f --- /dev/null +++ b/packages/manager/.changeset/pr-10403-tests-1714588716317.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Add Cypress test for Domain cloning ([#10403](https://github.com/linode/manager/pull/10403)) diff --git a/packages/manager/.changeset/pr-10403-tests-1714588819736.md b/packages/manager/.changeset/pr-10403-tests-1714588819736.md new file mode 100644 index 00000000000..bb82b13608f --- /dev/null +++ b/packages/manager/.changeset/pr-10403-tests-1714588819736.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Tests +--- + +Add Cypress test for Domain cloning ([#10403](https://github.com/linode/manager/pull/10403)) diff --git a/packages/manager/cypress/e2e/core/domains/smoke-clone-domain.spec.ts b/packages/manager/cypress/e2e/core/domains/smoke-clone-domain.spec.ts new file mode 100644 index 00000000000..f85218804e7 --- /dev/null +++ b/packages/manager/cypress/e2e/core/domains/smoke-clone-domain.spec.ts @@ -0,0 +1,137 @@ +import { Domain } from '@linode/api-v4'; +import { domainFactory } from '@src/factories'; +import { getClick, fbtClick, fbltClick } from 'support/helpers'; +import { authenticate } from 'support/api/authentication'; +import { randomDomainName } from 'support/util/random'; +import { createDomain } from '@linode/api-v4/lib/domains'; +import { createDomainRecords } from 'support/constants/domains'; +import { interceptCreateDomainRecord } from 'support/intercepts/domains'; +import { ui } from 'support/ui'; +import { cleanUp } from 'support/util/cleanup'; + +authenticate(); +describe('Clone a Domain', () => { + before(() => { + cleanUp('domains'); + }); + + /* + * - Clicks "Clone" action menu item for domain but cancels operation. + * - Clicks "Clone" action menu item for domain and confirms operation. + * - Confirms that a "Domain is not valid." error is yielded when entering an invalid domain name. + * - Confirms that the user is redirected to the new Domain's details page after cloning. + * - Confirms that domain is still in landing page list after canceled operation. + * - Confirms that cloned domains contain the same records as the original Domain. + */ + it('clones a domain', () => { + const domainRequest = domainFactory.build({ + domain: randomDomainName(), + group: 'test-group', + }); + + const invalidDomainName = 'invalid-domain-name'; + const clonedDomainName = randomDomainName(); + + const domainRecords = createDomainRecords(); + + cy.defer(createDomain(domainRequest), 'creating domain').then( + (domain: Domain) => { + // Add records to the domain. + cy.visitWithLogin(`/domains/${domain.id}`); + + domainRecords.forEach((rec) => { + interceptCreateDomainRecord().as('apiCreateRecord'); + fbtClick(rec.name); + rec.fields.forEach((f) => { + getClick(f.name).type(f.value); + }); + fbtClick('Save'); + cy.wait('@apiCreateRecord'); + }); + + cy.visitWithLogin('/domains'); + + // Confirm that domain is listed and initiate deletion. + cy.findByText(domain.domain) + .should('be.visible') + .closest('tr') + .within(() => { + ui.actionMenu + .findByTitle(`Action menu for Domain ${domain}`) + .should('be.visible') + .click(); + }); + ui.actionMenuItem.findByTitle('Clone').should('be.visible').click(); + + // Cancel cloning when prompted to confirm. + ui.drawer + .findByTitle(`Clone Domain`) + .should('be.visible') + .within(() => { + ui.buttonGroup + .findButtonByTitle('Cancel') + .should('be.visible') + .should('be.enabled') + .click(); + }); + + // Confirm that no new domain is added and initiate cloning again. + cy.findByText(domain.domain) + .should('be.visible') + .closest('tr') + .within(() => { + ui.actionMenu + .findByTitle(`Action menu for Domain ${domain}`) + .should('be.visible') + .click(); + }); + ui.actionMenuItem.findByTitle('Clone').should('be.visible').click(); + + // Confirm cloning. + ui.drawer + .findByTitle(`Clone Domain`) + .should('be.visible') + .within(() => { + // The button should be disabled before confirming the correct domain + ui.buttonGroup + .findButtonByTitle('Create Domain') + .should('be.visible') + .should('be.disabled'); + + // Confirm that an error is displayed when entering an invalid domain name + fbltClick('New Domain').type(invalidDomainName); + ui.buttonGroup + .findButtonByTitle('Create Domain') + .should('be.visible') + .should('be.enabled') + .click(); + cy.findByText('Domain is not valid.').should('be.visible'); + + fbltClick('New Domain').clear().type(clonedDomainName); + ui.buttonGroup + .findButtonByTitle('Create Domain') + .should('be.visible') + .should('be.enabled') + .click(); + }); + // After cloning a Domain, the user is redirected to the new Domain's details page + cy.url().should('endWith', 'domains'); + + // Confirm that domain is cloned and cloned domains contain the same records as the original Domain. + cy.visitWithLogin('/domains'); + cy.findByText(domain.domain).should('be.visible'); + cy.findByText(clonedDomainName).should('be.visible').click(); + domainRecords.forEach((rec) => { + cy.get(`[aria-label="${rec.tableAriaLabel}"]`).within((_table) => { + rec.fields.forEach((f) => { + if (f.skipCheck) { + return; + } + cy.findByText(f.value, { exact: !f.approximate }); + }); + }); + }); + } + ); + }); +}); diff --git a/packages/manager/cypress/e2e/core/domains/smoke-create-domain-records.spec.ts b/packages/manager/cypress/e2e/core/domains/smoke-create-domain-records.spec.ts index b051f09b61d..379386f9258 100644 --- a/packages/manager/cypress/e2e/core/domains/smoke-create-domain-records.spec.ts +++ b/packages/manager/cypress/e2e/core/domains/smoke-create-domain-records.spec.ts @@ -4,95 +4,7 @@ import { createDomain } from 'support/api/domains'; import { fbtClick, getClick } from 'support/helpers'; import { interceptCreateDomainRecord } from 'support/intercepts/domains'; import { cleanUp } from 'support/util/cleanup'; -import { - randomDomainName, - randomIp, - randomLabel, - randomString, -} from 'support/util/random'; - -const createRecords = () => [ - { - name: 'Add an A/AAAA Record', - tableAriaLabel: 'List of Domains A/AAAA Record', - fields: [ - { - name: '[data-qa-target="Hostname"]', - value: randomLabel(), - skipCheck: false, - }, - { - name: '[data-qa-target="IP Address"]', - value: `${randomIp()}`, - skipCheck: false, - }, - ], - }, - { - name: 'Add a CNAME Record', - tableAriaLabel: 'List of Domains CNAME Record', - fields: [ - { - name: '[data-qa-target="Hostname"]', - value: randomLabel(), - skipCheck: false, - }, - { - name: '[data-qa-target="Alias to"]', - value: `${randomLabel()}.net`, - skipCheck: false, - }, - ], - }, - { - name: 'Add a TXT Record', - tableAriaLabel: 'List of Domains TXT Record', - fields: [ - { - name: '[data-qa-target="Hostname"]', - value: randomLabel(), - skipCheck: false, - }, - { - name: '[data-qa-target="Value"]', - value: `${randomLabel()}=${randomString()}`, - skipCheck: false, - }, - ], - }, - { - name: 'Add an SRV Record', - tableAriaLabel: 'List of Domains SRV Record', - fields: [ - { - name: '[data-qa-target="Service"]', - value: randomLabel(), - skipCheck: true, - }, - { - name: '[data-qa-target="Target"]', - value: randomLabel(), - approximate: true, - }, - ], - }, - { - name: 'Add a CAA Record', - tableAriaLabel: 'List of Domains CAA Record', - fields: [ - { - name: '[data-qa-target="Name"]', - value: randomLabel(), - skipCheck: false, - }, - { - name: '[data-qa-target="Value"]', - value: randomDomainName(), - skipCheck: false, - }, - ], - }, -]; +import { createDomainRecords } from 'support/constants/domains'; authenticate(); describe('Creates Domains record with Form', () => { @@ -100,7 +12,7 @@ describe('Creates Domains record with Form', () => { cleanUp('domains'); }); - createRecords().forEach((rec) => { + createDomainRecords().forEach((rec) => { return it(rec.name, () => { createDomain().then((domain) => { // intercept create api record request diff --git a/packages/manager/cypress/support/constants/domains.ts b/packages/manager/cypress/support/constants/domains.ts new file mode 100644 index 00000000000..0eedbece6c2 --- /dev/null +++ b/packages/manager/cypress/support/constants/domains.ts @@ -0,0 +1,90 @@ +import { + randomLabel, + randomIp, + randomString, + randomDomainName, +} from 'support/util/random'; + +// Array of domain records for which to test creation. +export const createDomainRecords = () => [ + { + name: 'Add an A/AAAA Record', + tableAriaLabel: 'List of Domains A/AAAA Record', + fields: [ + { + name: '[data-qa-target="Hostname"]', + value: randomLabel(), + skipCheck: false, + }, + { + name: '[data-qa-target="IP Address"]', + value: `${randomIp()}`, + skipCheck: false, + }, + ], + }, + { + name: 'Add a CNAME Record', + tableAriaLabel: 'List of Domains CNAME Record', + fields: [ + { + name: '[data-qa-target="Hostname"]', + value: randomLabel(), + skipCheck: false, + }, + { + name: '[data-qa-target="Alias to"]', + value: `${randomLabel()}.net`, + skipCheck: false, + }, + ], + }, + { + name: 'Add a TXT Record', + tableAriaLabel: 'List of Domains TXT Record', + fields: [ + { + name: '[data-qa-target="Hostname"]', + value: randomLabel(), + skipCheck: false, + }, + { + name: '[data-qa-target="Value"]', + value: `${randomLabel()}=${randomString()}`, + skipCheck: false, + }, + ], + }, + { + name: 'Add an SRV Record', + tableAriaLabel: 'List of Domains SRV Record', + fields: [ + { + name: '[data-qa-target="Service"]', + value: randomLabel(), + skipCheck: true, + }, + { + name: '[data-qa-target="Target"]', + value: randomLabel(), + approximate: true, + }, + ], + }, + { + name: 'Add a CAA Record', + tableAriaLabel: 'List of Domains CAA Record', + fields: [ + { + name: '[data-qa-target="Name"]', + value: randomLabel(), + skipCheck: false, + }, + { + name: '[data-qa-target="Value"]', + value: randomDomainName(), + skipCheck: false, + }, + ], + }, +];