Skip to content

Commit

Permalink
test: [M3-8478] - Fix Cypress StackScript Linode deploy test flake (#…
Browse files Browse the repository at this point in the history
…10826)

* Add account availability intercept util

* Scroll desired autocomplete item into view

* Improve region selection in StackScript Linode deploy test, improve StackScript input speed

* Added changeset: Resolve StackScript Linode deploy test flake
  • Loading branch information
jdamore-linode committed Aug 27, 2024
1 parent 9514b2c commit e893f16
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 23 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-10826-tests-1724431261722.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Resolve StackScript Linode deploy test flake ([#10826](https://github.com/linode/manager/pull/10826))
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
pollLinodeDiskSize,
} from 'support/util/polling';
import { randomLabel, randomString, randomPhrase } from 'support/util/random';
import { interceptGetAccountAvailability } from 'support/intercepts/account';
import {
interceptCreateStackScript,
interceptGetStackScripts,
Expand All @@ -13,7 +14,7 @@ import { interceptCreateLinode } from 'support/intercepts/linodes';
import { ui } from 'support/ui';
import { createLinodeRequestFactory } from 'src/factories';
import { createImage, getLinodeDisks, resizeLinodeDisk } from '@linode/api-v4';
import { chooseRegion } from 'support/util/regions';
import { chooseRegion, getRegionByLabel } from 'support/util/regions';
import { SimpleBackoffMethod } from 'support/util/backoff';
import { cleanUp } from 'support/util/cleanup';
import { createTestLinode } from 'support/util/linodes';
Expand All @@ -35,6 +36,20 @@ const stackScriptErrorNoShebang =
const stackScriptErrorUdfAlphanumeric =
'UDF names can only contain alphanumeric and underscore characters.';

/**
* Sets the StackScript field's value programmatically rather than via simulated typing.
*
* Cypress's typing operation is slow for long strings, so we can save several
* seconds by setting the value directly, then simulating a couple keystrokes.
*
* @param script - Script contents to input.
*/
const inputStackScript = (script: string) => {
cy.get('[data-qa-textfield-label="Script"]').should('be.visible').click();

cy.focused().invoke('val', script).type(' {backspace}');
};

/**
* Fills out the StackScript creation form.
*
Expand Down Expand Up @@ -69,11 +84,8 @@ const fillOutStackscriptForm = (

cy.findByText(`${targetImage}`).should('be.visible').click();

// Insert a script with invalid UDF data.
cy.get('[data-qa-textfield-label="Script"]')
.should('be.visible')
.click()
.type(script);
// Insert a script.
inputStackScript(script);
};

/**
Expand All @@ -87,9 +99,14 @@ const fillOutStackscriptForm = (
*/
const fillOutLinodeForm = (label: string, regionName: string) => {
const password = randomString(32);
const region = getRegionByLabel(regionName);

ui.regionSelect.find().click();
ui.regionSelect.findItemByRegionLabel(regionName).click();
ui.regionSelect
.findItemByRegionLabel(regionName)
.should('be.visible')
.click();
ui.regionSelect.find().should('have.value', `${region.label} (${region.id})`);

cy.findByText('Linode Label')
.should('be.visible')
Expand Down Expand Up @@ -176,6 +193,7 @@ describe('Create stackscripts', () => {
interceptCreateStackScript().as('createStackScript');
interceptGetStackScripts().as('getStackScripts');
interceptCreateLinode().as('createLinode');
interceptGetAccountAvailability().as('getAvailability');

cy.visitWithLogin('/stackscripts/create');

Expand All @@ -199,11 +217,7 @@ describe('Create stackscripts', () => {
cy.findByText(stackScriptErrorNoShebang).should('be.visible');

cy.fixture(stackscriptUdfInvalidPath).then((stackScriptUdfInvalid) => {
cy.get('[data-qa-textfield-label="Script"]')
.should('be.visible')
.click()
.type('{selectall}{backspace}')
.type(stackScriptUdfInvalid);
inputStackScript(stackScriptUdfInvalid);
});

ui.buttonGroup
Expand All @@ -217,11 +231,7 @@ describe('Create stackscripts', () => {

// Insert a script with valid UDF data and submit StackScript create form.
cy.fixture(stackscriptUdfPath).then((stackScriptUdf) => {
cy.get('[data-qa-textfield-label="Script"]')
.should('be.visible')
.click()
.type('{selectall}{backspace}')
.type(stackScriptUdf);
inputStackScript(stackScriptUdf);
});

ui.buttonGroup
Expand Down Expand Up @@ -252,6 +262,9 @@ describe('Create stackscripts', () => {
.should('be.enabled')
.click();

// Wait for availability to be retrieved before interacting with form.
cy.wait('@getAvailability');

// Fill out Linode creation form, confirm UDF fields behave as expected.
fillOutLinodeForm(linodeLabel, linodeRegion.label);

Expand All @@ -276,7 +289,10 @@ describe('Create stackscripts', () => {

// Confirm that Linode has been created and is provisioning.
cy.findByText(linodeLabel).should('be.visible');
cy.findByText('PROVISIONING').should('be.visible');

// In rare cases, the Linode can provision quicker than this assertion happens,
// so we want to account for cases where it's already booting or even running.
cy.findByText(/(PROVISIONING|BOOTING|RUNNING)/).should('be.visible');
});

/*
Expand Down
9 changes: 9 additions & 0 deletions packages/manager/cypress/support/intercepts/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,12 @@ export const mockGetMaintenance = (
}
});
};

/**
* Intercepts GET request to fetch account region availability.
*
* @returns Cypress chainable.
*/
export const interceptGetAccountAvailability = (): Cypress.Chainable<null> => {
return cy.intercept('GET', apiMatcher('account/availability*'));
};
16 changes: 11 additions & 5 deletions packages/manager/cypress/support/ui/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,17 @@ export const autocompletePopper = {
title: string,
options?: SelectorMatcherOptions
): Cypress.Chainable => {
return cy
.document()
.its('body')
.find('[data-qa-autocomplete-popper]')
.findByText(title, options);
return (
cy
.document()
.its('body')
.find('[data-qa-autocomplete-popper]')
.findByText(title, options)
// Scroll to the desired item before yielding.
// Apply a negative top offset to account for cases where the desired
// item may be obscured by the drop-down sticky category heading.
.scrollIntoView({ offset: { left: 0, top: -45 } })
);
},
};

Expand Down

0 comments on commit e893f16

Please sign in to comment.