Skip to content

Commit 94d807d

Browse files
authored
Merge pull request #1154 from jescalada/cypress-test-data-dependency
test: fix Cypress test data dependency
2 parents ef79ca4 + 51da326 commit 94d807d

File tree

7 files changed

+112
-53
lines changed

7 files changed

+112
-53
lines changed

cypress.config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,13 @@ module.exports = defineConfig({
44
e2e: {
55
baseUrl: process.env.CYPRESS_BASE_URL || 'http://localhost:3000',
66
chromeWebSecurity: false, // Required for OIDC testing
7+
setupNodeEvents(on, config) {
8+
on("task", {
9+
log(message) {
10+
console.log(message);
11+
return null;
12+
}
13+
})
14+
}
715
},
816
});

cypress/e2e/repo.cy.js

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,84 @@
11
describe('Repo', () => {
2-
beforeEach(() => {
2+
let repoName;
3+
let cloneURL;
4+
let csrfToken;
5+
let cookies;
6+
let repoId;
7+
8+
before(() => {
39
cy.login('admin', 'admin');
410

5-
cy.visit('/dashboard/repo');
11+
// Create a new repo
12+
cy.getCSRFToken().then((csrfToken) => {
13+
repoName = `${Date.now()}`;
14+
cloneURL = `http://localhost:8000/github.com/cypress-test/${repoName}.git`;
15+
16+
cy.request({
17+
method: 'POST',
18+
url: 'http://localhost:8080/api/v1/repo',
19+
body: {
20+
project: 'cypress-test',
21+
name: repoName,
22+
url: `https://github.com/cypress-test/${repoName}.git`
23+
},
24+
headers: {
25+
cookie: cookies?.join('; ') || '',
26+
'X-CSRF-TOKEN': csrfToken
27+
}
28+
}).then((res) => {
29+
expect(res.status).to.eq(200);
30+
repoId = res.body._id;
31+
});
32+
});
33+
});
634

7-
// prevent failures on 404 request and uncaught promises
35+
it('Opens tooltip with correct content and can copy', () => {
36+
cy.visit('/dashboard/repo');
837
cy.on('uncaught:exception', () => false);
38+
39+
const tooltipQuery = 'div[role="tooltip"]';
40+
41+
// Check the tooltip isn't open to start with
42+
cy.get(tooltipQuery)
43+
.should('not.exist');
44+
45+
// Find the repo's Code button and click it
46+
cy.get(`a[href="/dashboard/repo/${repoId}"]`)
47+
.closest('tr')
48+
.find('span')
49+
.contains('Code')
50+
.should('exist')
51+
.click();
52+
53+
// Check tooltip is open and contains the correct clone URL
54+
cy.get(tooltipQuery)
55+
.should('exist')
56+
.find('span')
57+
.contains(cloneURL)
58+
.should('exist')
59+
.parent()
60+
.find('span')
61+
.next()
62+
.get('svg.octicon-copy')
63+
.should('exist')
64+
.click()
65+
.get('svg.octicon-copy')
66+
.should('not.exist')
67+
.get('svg.octicon-check')
68+
.should('exist');
969
});
1070

11-
describe('Code button for repo row', () => {
12-
it('Opens tooltip with correct content and can copy', () => {
13-
const cloneURLRegex = /http:\/\/localhost:8000\/(?:[^\/]+\/).+\.git/;
14-
const tooltipQuery = 'div[role="tooltip"]';
15-
16-
cy
17-
// tooltip isn't open to start with
18-
.get(tooltipQuery)
19-
.should('not.exist');
20-
21-
cy
22-
// find a table row for a repo (any will do)
23-
.get('table#RepoListTable>tbody>tr')
24-
// find the nearby span containing Code we can click to open the tooltip
25-
.find('span')
26-
.contains('Code')
27-
.should('exist')
28-
.click();
29-
30-
cy
31-
// find the newly opened tooltip
32-
.get(tooltipQuery)
33-
.should('exist')
34-
.find('span')
35-
// check it contains the url we expect
36-
.contains(cloneURLRegex)
37-
.should('exist')
38-
.parent()
39-
// find the adjacent span that contains the svg
40-
.find('span')
41-
.next()
42-
// check it has the copy icon first and click it
43-
.get('svg.octicon-copy')
44-
.should('exist')
45-
.click()
46-
// check the icon has changed to the check icon
47-
.get('svg.octicon-copy')
48-
.should('not.exist')
49-
.get('svg.octicon-check')
50-
.should('exist');
51-
52-
// failed to successfully check the clipboard
71+
after(() => {
72+
// Delete the repo
73+
cy.getCSRFToken().then((csrfToken) => {
74+
cy.request({
75+
method: 'DELETE',
76+
url: `http://localhost:8080/api/v1/repo/${repoName}/delete`,
77+
headers: {
78+
cookie: cookies?.join('; ') || '',
79+
'X-CSRF-TOKEN': csrfToken
80+
}
81+
});
5382
});
5483
});
5584
});

cypress/support/commands.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,25 @@ Cypress.Commands.add('login', (username, password) => {
3939
cy.url().should('include', '/dashboard/repo');
4040
});
4141
});
42+
43+
Cypress.Commands.add('getCSRFToken', () => {
44+
return cy.request('GET', 'http://localhost:8080/api/v1/repo').then((res) => {
45+
let cookies = res.headers['set-cookie'];
46+
47+
if (typeof cookies === 'string') {
48+
cookies = [cookies];
49+
}
50+
51+
if (!cookies) {
52+
throw new Error('No cookies found in response');
53+
}
54+
55+
const csrfCookie = cookies.find(c => c.startsWith('csrf='));
56+
if (!csrfCookie) {
57+
throw new Error('No CSRF cookie found in response headers');
58+
}
59+
60+
const token = csrfCookie.split('=')[1].split(';')[0];
61+
return cy.wrap(decodeURIComponent(token));
62+
});
63+
});

src/ui/components/Tasks/Tasks.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
import classnames from 'classnames';
3+
import clsx from 'clsx';
44
import { makeStyles } from '@material-ui/core/styles';
55
import Checkbox from '@material-ui/core/Checkbox';
66
import Tooltip from '@material-ui/core/Tooltip';
@@ -30,7 +30,7 @@ export default function Tasks(props) {
3030
setChecked(newChecked);
3131
};
3232
const { tasksIndexes, tasks, rtlActive } = props;
33-
const tableCellClasses = classnames(classes.tableCell, {
33+
const tableCellClasses = clsx(classes.tableCell, {
3434
[classes.tableCellRTL]: rtlActive,
3535
});
3636
return (
@@ -60,7 +60,7 @@ export default function Tasks(props) {
6060
classes={{ tooltip: classes.tooltip }}
6161
>
6262
<IconButton aria-label='Edit' className={classes.tableActionButton}>
63-
<Edit className={classes.tableActionButtonIcon + ' ' + classes.edit} />
63+
<Edit className={clsx(classes.tableActionButtonIcon, classes.edit)} />
6464
</IconButton>
6565
</Tooltip>
6666
<Tooltip
@@ -70,7 +70,7 @@ export default function Tasks(props) {
7070
classes={{ tooltip: classes.tooltip }}
7171
>
7272
<IconButton aria-label='Close' className={classes.tableActionButton}>
73-
<Close className={classes.tableActionButtonIcon + ' ' + classes.close} />
73+
<Close className={clsx(classes.tableActionButtonIcon, classes.close)} />
7474
</IconButton>
7575
</Tooltip>
7676
</TableCell>

src/ui/services/repo.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ const getRepos = async (
4242
setIsLoading(true);
4343
await axios(url.toString(), getAxiosConfig())
4444
.then((response) => {
45-
const data = response.data;
46-
setData(data);
45+
const sortedRepos = response.data.sort((a, b) => a.name.localeCompare(b.name));
46+
setData(sortedRepos);
4747
})
4848
.catch((error) => {
4949
setIsError(true);

test/processors/blockForAuth.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ describe('blockForAuth', () => {
125125
expect(result).to.equal(action);
126126
}),
127127
{
128-
numRuns: 100
128+
numRuns: 1000
129129
}
130130
);
131131
});

test/testCheckRepoInAuthList.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('Check a Repo is in the authorised list', async () => {
4545
const result = await processor.exec(null, action);
4646
expect(result.error).to.be.true;
4747
}),
48-
{ numRuns: 100 },
48+
{ numRuns: 1000 },
4949
);
5050
});
5151
});

0 commit comments

Comments
 (0)