Skip to content

Commit

Permalink
(tests) Adds first iteration of E2E tests for cluster upgrades
Browse files Browse the repository at this point in the history
  • Loading branch information
amrutac committed Aug 24, 2017
1 parent 405ca9f commit c7ce400
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
/frontend/public/dist
/frontend/npm-debug.log
/frontend/yarn-error.log
/frontend/tests_output
42 changes: 42 additions & 0 deletions frontend/integration-tests/pages/clusterUpgradePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module.exports = {
elements: {
expandClusterUpdatesLink: {
selector: '#expand-cluster-updates'
},
showDetailsLink: {
selector: '//button[contains(@class, "co-cluster-updates__operator-show-details")]',
locateStrategy: 'xpath'
},
channelState: {
selector: '#channel-state'
},
updatesButton: {
selector: '//button[contains(@class, "co-cluster-updates__action-button")]',
locateStrategy: 'xpath'
},
uptoDateDiv: {
selector: '//div[contains(@class, "co-cluster-updates__operator-icon co-cluster-updates__operator-icon--up-to-date")]',
locateStrategy: 'xpath'
},
pendingUpdatesDiv: {
selector: '//div[contains(@class, "co-cluster-updates__operator-icon co-cluster-updates__operator-icon--pending")]',
locateStrategy: 'xpath'
},
updatingSpan: {
selector: '//span[contains(@class, "co-cluster-updates__operator-subheader")]',
locateStrategy: 'xpath'
},
updateTCODiv: {
selector: '//div[@data-id="Update Tectonic Operators"]',
locateStrategy: 'xpath'
},
updateAppVersionDiv: {
selector: '//div[@data-id="Update AppVersion components"]',
locateStrategy: 'xpath'
},
cleanupStatusDiv: {
selector: '//div[@data-id="Cleanup unwanted old resources"]',
locateStrategy: 'xpath'
}
}
};
File renamed without changes.
65 changes: 65 additions & 0 deletions frontend/integration-tests/tests/cluster-upgrade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const _ = require('lodash');
const TIMEOUT = 4000;
const UPGRADE_TIMEOUT = 10000;

const clusterUpgradeTests_ = {};

const initTest = (browser, cb) => {
const clusterUpgradePage = browser.page.clusterUpgradePage();
const url = `${browser.launch_url}/settings/cluster`;
clusterUpgradePage
.navigate(url)
.waitForElementVisible('@expandClusterUpdatesLink', TIMEOUT)
.click('@expandClusterUpdatesLink')
.getText('@channelState', ({value}) => cb(value, clusterUpgradePage));
};

const assertChannelState = (channelState, client) => {
console.log(`Asserting State for ${channelState}`);
if (channelState === 'Up to date') {
client.expect.element('@uptoDateDiv').to.be.visible;
} else if (_.endsWith(channelState, 'is available')) {
client.expect.element('@pendingUpdatesDiv').to.be.visible;
} else if (channelState === 'Updating' || channelState === 'Paused...') {
client.expect.element('@updatingSpan').to.be.visible;
}
};

const assertUpdatingStatus = (channelState, client) => {
console.log(`Asserting Status for ${channelState}`);
client.expect.element('@updateTCODiv').to.be.visible;
client.expect.element('@updateAppVersionDiv').to.be.visible;
client.expect.element('@cleanupStatusDiv').to.be.visible;
};

clusterUpgradeTests_['Check for Updates'] = browser => {
initTest(browser, assertChannelState);
};

clusterUpgradeTests_['Trigger Updates'] = browser => {
initTest(browser, (channelState, clusterUpgradePage) => {
if (channelState !== 'Up to date') {
if (_.endsWith(channelState, 'is available') || channelState === 'Paused...') {
clusterUpgradePage.click('@updatesButton')
.waitForElementVisible('@showDetailsLink', TIMEOUT);
} else if (channelState === 'Updating') {
clusterUpgradePage.click('@showDetailsLink');
}

clusterUpgradePage.click('@showDetailsLink');
assertUpdatingStatus(channelState, clusterUpgradePage);
//TODO: [amrutac] This could take longer, figure out a way to retry this test.
clusterUpgradePage.waitForElementVisible('@uptoDateDiv', UPGRADE_TIMEOUT)
.getText('@channelState', ({value}) => {
clusterUpgradePage.verify.equal(value, 'Up to date');
});
} else {
console.log('Updates are not available at this time.');
}

});
};

clusterUpgradeTests_.after = browser => browser.end();

module.exports = clusterUpgradeTests_;
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const navigate = (browser, path, cb) => {

const TIMEOUT = 4000;

const exports_ = {};
const crudTests_ = {};

[
'daemonsets',
Expand All @@ -33,20 +33,21 @@ const exports_ = {};
'statefulsets',
'roles',
].forEach(resource => {
exports_[`YAML - ${resource}`] = browser => {
const utils = browser.page.utils();
crudTests_[`YAML - ${resource}`] = browser => {
const crudPage = browser.page.crudPage();

console.log('Testing', resource);
navigate(browser, `/all-namespaces/${resource}`, () => {
utils
crudPage
.waitForElementVisible('@CreateYAMLButton', TIMEOUT)
.click('@CreateYAMLButton')
.click('@saveYAMLButton')
.waitForElementVisible('@actionsDropdownButton', TIMEOUT);

browser.assert.urlContains('/example/details');
//with verify(), when an assertion fails, the test logs the failure and continues with other assertions.
browser.verify.urlContains('/example/details');

utils
crudPage
.click('@actionsDropdownButton')
.click('@actionsDropdownDeleteLink')
.waitForElementVisible('@deleteModalConfirmButton', TIMEOUT)
Expand All @@ -56,6 +57,6 @@ const exports_ = {};
};
});

exports_.after = browser => browser.end();
crudTests_.after = browser => browser.end();

module.exports = exports_;
module.exports = crudTests_;
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"coverage": "jest --coverage .",
"lint": "eslint --ext .js,.jsx,.ts,.tsx --color .",
"test": "jest",
"test-gui": "nightwatch --test integration-tests/tests/gui.js",
"test-gui": "nightwatch --test integration-tests/tests/crud.js",
"analyze": "NODE_ENV=production webpack --profile --json | awk '{if(NR>1)print}' > public/dist/stats.json && webpack-bundle-analyzer --mode static -r public/dist/report.html public/dist/stats.json"
},
"jest": {
Expand Down
6 changes: 3 additions & 3 deletions frontend/public/components/channel-operators/app-version.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const Header = ({channelState, tcAppVersion, expanded, onClick}) => {
<OperatorState opState={channelState} version={tcAppVersion.desiredVersion} />
</div>
}
<a className="co-cluster-updates__toggle" onClick={onClick}>{expanded ? 'Collapse' : 'Expand'}</a>
<a className="co-cluster-updates__toggle" id="expand-cluster-updates" onClick={onClick}>{expanded ? 'Collapse' : 'Expand'}</a>
</div>;
};

Expand Down Expand Up @@ -144,7 +144,7 @@ class UpToDateTectonicCluster extends React.Component {
<div className="co-cluster-updates__operator-icon co-cluster-updates__operator-icon--up-to-date">
<span className="fa fa-fw fa-check-circle"></span>
</div>
<div className="co-cluster-updates__operator-text"> <span>{name} {currentVersion}</span></div>
<div className="co-cluster-updates__operator-text" id="up-to-date-cluster"> <span>{name} {currentVersion}</span></div>
</div>
<div className="co-cluster-updates__operator-details">
<button className="btn btn-link" onClick={() => this.setState({showDetails: !this.state.showDetails})}>
Expand Down Expand Up @@ -265,7 +265,7 @@ const TaskStatusStep = ({status, style}) => {
<div className={`co-cluster-updates__operator-icon co-cluster-updates__operator-ts--${suffix}`}>
<span className={classNames('fa fa-fw', icon)}></span>
</div>
<div className={(!_.has(status, 'statuses') && status.type === 'appversion' && status.state === 'Running') ? 'co-cluster-updates__operator-text co-cluster-updates__operator-text--running' : 'co-cluster-updates__operator-text'}>
<div className={(!_.has(status, 'statuses') && status.type === 'appversion' && status.state === 'Running') ? 'co-cluster-updates__operator-text co-cluster-updates__operator-text--running' : 'co-cluster-updates__operator-text'} data-id={status.name}>
{name}
</div>
</div>;
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/components/utils/operator-states.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const OperatorState = ({opState, version}) => {
return <LoadingInline />;
}

return <span className={`co-cluster-updates--${_.get(operatorState, 'suffix', '')}`}>
return <span className={`co-cluster-updates--${_.get(operatorState, 'suffix', '')}`} id="channel-state">
{icon && <span className={`co-cluster-updates__text-icon fa ${icon} co-cluster-updates__operator-icon--${_.get(operatorState, 'suffix', '')}`}></span>}
{opState === 'UpdateAvailable' && version } {_.get(operatorState, 'statusText', '')}
</span>;
Expand Down

0 comments on commit c7ce400

Please sign in to comment.