Skip to content

Commit 1ad3d59

Browse files
authored
Merge pull request #1803 from 4dn-dcic/npm_updates_apr_2023
Npm Updates Apr-May 2023
2 parents d7625b7 + 7b95d68 commit 1ad3d59

File tree

10 files changed

+963
-762
lines changed

10 files changed

+963
-762
lines changed

CHANGELOG.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,24 @@ fourfront
66
Change Log
77
----------
88

9+
5.3.4
10+
=====
11+
12+
`PR Npm Updates Apr-May 2023 <https://github.com/4dn-dcic/fourfront/pull/1803>`_
13+
14+
* jsonwebtoken npm package is replaced with jose
15+
* cypress 10 to 12 migration completed
16+
* new cypress test for not facet feature added
17+
* auth0 client/domain grabbed from /auth0_config in cypress tests (old implementation gets them from env. variables)
18+
19+
920
5.3.3
1021
=====
1122

1223
* updated suggested_enums for processed files
1324
* updated assay_subclass_short by making a more general FISH at expense of RNA and DNA FISH
1425

26+
1527
5.3.2
1628
=====
1729

deploy/post_deploy_testing/cypress.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ module.exports = defineConfig({
1717
},
1818
baseUrl: 'https://data.4dnucleome.org',
1919
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
20+
testIsolation: false
2021
},
2122
});

deploy/post_deploy_testing/cypress/e2e/04a_search_views_local.cy.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,9 @@ describe('Deployment/CI Search View Tests', function () {
2828
cy.get('input#field_for_tags.form-control').focus().type('deleted_by_cypress_test').wait(100).end();
2929

3030
// Click Validate button
31-
cy.get(".action-buttons-container .btn")
32-
.within(function () {
33-
return cy.contains('Validate').click().end().wait(1000);
34-
}).end()
35-
//Click Submit button
36-
.get(".action-buttons-container .btn").within(function () {
37-
return cy.contains('Submit').click().end().wait(1000);
38-
}).end();
31+
cy.get(".action-buttons-container").as("editButtons");
32+
cy.get("@editButtons").find('button.btn').contains('Validate').click().end().wait(1000).end();
33+
cy.get("@editButtons").find('button.btn').contains('Submit').click().end().wait(1000).end();
3934
});
4035
}
4136

@@ -61,9 +56,16 @@ describe('Deployment/CI Search View Tests', function () {
6156
cy.visit('/pages'); // We should get redirected to ?type=Page
6257
});
6358

64-
beforeEach(function(){
59+
beforeEach(function () {
6560
// Ensure we preserve search session cookie for proper ordering.
66-
Cypress.Cookies.preserveOnce("searchSessionID");
61+
cy.session('preserveCookies', () => {
62+
// Ensure we preserve search session cookie for proper ordering.
63+
cy.getCookie('searchSessionID').then((cookie) => {
64+
if (cookie) {
65+
cy.setCookie('searchSessionID', cookie.value);
66+
}
67+
});
68+
});
6769
});
6870

6971
it('Should redirect to /search/?type=Page correctly', function(){
@@ -384,9 +386,16 @@ describe('Deployment/CI Search View Tests', function () {
384386
cy.visit('/'); // Start at home page
385387
});
386388

387-
beforeEach(function(){
389+
beforeEach(function () {
388390
// Ensure we preserve search session cookie for proper ordering.
389-
Cypress.Cookies.preserveOnce("searchSessionID");
391+
cy.session('preserveCookies', () => {
392+
// Ensure we preserve search session cookie for proper ordering.
393+
cy.getCookie('searchSessionID').then((cookie) => {
394+
if (cookie) {
395+
cy.setCookie('searchSessionID', cookie.value);
396+
}
397+
});
398+
});
390399
});
391400

392401
it('SearchBox input works, goes to /browse/ on submit', function(){

deploy/post_deploy_testing/cypress/e2e/04b_search_views.cy.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@ describe('Post-Deployment Search View Tests', function () {
88
cy.visit('/search/');
99
});
1010

11-
beforeEach(function(){
11+
beforeEach(function () {
1212
// Ensure we preserve search session cookie for proper ordering.
13-
Cypress.Cookies.preserveOnce("searchSessionID");
13+
cy.session('preserveCookies', () => {
14+
// Ensure we preserve search session cookie for proper ordering.
15+
cy.getCookie('searchSessionID').then((cookie) => {
16+
if (cookie) {
17+
cy.setCookie('searchSessionID', cookie.value);
18+
}
19+
});
20+
});
1421
});
1522

1623
it('Load as you scroll works for ?type=Item', function () {
@@ -55,9 +62,16 @@ describe('Post-Deployment Search View Tests', function () {
5562
cy.visit('/search/');
5663
});
5764

58-
beforeEach(function(){
65+
beforeEach(function () {
5966
// Ensure we preserve search session cookie for proper ordering.
60-
Cypress.Cookies.preserveOnce("searchSessionID");
67+
cy.session('preserveCookies', () => {
68+
// Ensure we preserve search session cookie for proper ordering.
69+
cy.getCookie('searchSessionID').then((cookie) => {
70+
if (cookie) {
71+
cy.setCookie('searchSessionID', cookie.value);
72+
}
73+
});
74+
});
6175
});
6276

6377
it('Starting from /search/, typing "olfactory" into searchbox redirects back to search', function () {

deploy/post_deploy_testing/cypress/e2e/07_higlass_display.cy.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ describe("HiGlass Display pages", function(){
1212

1313
context('Higlass Display summary page', function(){
1414

15+
// testIsolation that is a part of Cypress 12 migration is breaking the current test execution.
16+
// Adding "testIsolation: false" into cypress.config.js is the workaround to run tests as it was before, but
17+
// it is not a complete solution. So, we added beforeEach to clear cookies and local storage as it is descibed in:
18+
// https://docs.cypress.io/guides/references/migration-guide#Simulating-Pre-Test-Isolation-Behavior
19+
beforeEach(() => {
20+
cy.clearLocalStorage();
21+
cy.clearCookies();
22+
// other beforeEach logic to restore the expected local storage or cookies needed on the client.
23+
});
24+
1525
it('Can visit HiGlass Display collection page without login', function(){
1626

1727
// Visit the page and confirm you can see the table and facet properties.
@@ -58,6 +68,8 @@ describe("HiGlass Display pages", function(){
5868
var testItemsToDelete = [];
5969

6070
beforeEach(function() {
71+
cy.clearLocalStorage();
72+
cy.clearCookies();
6173
// Log in.
6274
cy.visit('/higlass-view-configs/').login4DN({ 'email': '[email protected]', 'useEnvToken' : true }).wait(500);
6375
});
@@ -119,8 +131,7 @@ describe("HiGlass Display pages", function(){
119131
cy.visit(draftUrl);
120132

121133
// When the app creates a new HiGlass display, we'll capture the JSON of the POST call.
122-
cy.server();
123-
cy.route('POST', '/higlass-view-configs/').as('newHiglassDisplay');
134+
cy.intercept('POST', '/higlass-view-configs/').as('newHiglassDisplay');
124135

125136
// Ensure HiGlassComponent has loaded (before Clone btn can be clicked w/o errors)
126137
cy.get('.higlass-instance .react-grid-layout').end()
@@ -131,16 +142,16 @@ describe("HiGlass Display pages", function(){
131142
}).end()
132143
.get('.alert div').should('contain.text', 'Saved new display.').end()
133144
// Inspect POST response.
134-
.get('@newHiglassDisplay').then(function (xhr) {
145+
.get('@newHiglassDisplay').then(function ({ request, response }) {
135146

136147
// Expect a 201 response.
137-
expect(xhr.status).to.eq(201);
148+
expect(response.statusCode).to.eq(201);
138149

139150
// Expect a new uuid.
140-
expect(xhr.responseBody["@graph"][0]["uuid"]).to.not.equal("00000000-1111-0000-1111-000000000002");
151+
expect(response.body["@graph"][0]["uuid"]).to.not.equal("00000000-1111-0000-1111-000000000002");
141152

142153
// Add the test Item so we can delete it later.
143-
testItemsToDelete.push(xhr.responseBody["@graph"][0]);
154+
testItemsToDelete.push(response.body["@graph"][0]);
144155
})
145156
.end()
146157
// Wait for HiGlass to fully be initialized as well, to avoid __zoom error perhaps.
@@ -159,8 +170,7 @@ describe("HiGlass Display pages", function(){
159170
cy.visit(draftUrl);
160171

161172
// There will be an AJAX response to a POST for the new Higlass display, so capture it here.
162-
cy.server();
163-
cy.route('POST', '/higlass-view-configs/').as('newHiglassDisplay');
173+
cy.intercept('POST', '/higlass-view-configs/').as('newHiglassDisplay');
164174

165175
// Ensure HiGlassComponent has loaded (before Clone btn can be clicked w/o errors)
166176
cy.get('.higlass-instance .react-grid-layout').end()
@@ -175,17 +185,17 @@ describe("HiGlass Display pages", function(){
175185
.get('.alert div').should('contain.text', 'Saved new display.').end()
176186

177187
// Inspect the AJAX response so we can capture the new uuid.
178-
.get('@newHiglassDisplay').then(function (xhr) {
188+
.get('@newHiglassDisplay').then(function ({ request, response }) {
179189

180190
// Expect a 201 response.
181-
expect(xhr.status).to.eq(201);
191+
expect(response.statusCode).to.eq(201);
182192

183193
// Expect a new uuid.
184-
expect(xhr.responseBody["@graph"][0]["uuid"]).to.not.equal("00000000-1111-0000-1111-000000000002");
194+
expect(response.body["@graph"][0]["uuid"]).to.not.equal("00000000-1111-0000-1111-000000000002");
185195

186196
// Add the test uuid so we can delete it later.
187-
testItemsToDelete.push(xhr.responseBody["@graph"][0]);
188-
const newID = xhr.responseBody["@graph"][0]["@id"];
197+
testItemsToDelete.push(response.body["@graph"][0]);
198+
const newID = response.body["@graph"][0]["@id"];
189199
expect(newID).to.be.ok;
190200

191201
// Clicking the SaveAs button should redirect us to the new page
@@ -222,6 +232,12 @@ describe("HiGlass Display pages", function(){
222232

223233
context('Sharing on the Individual Higlass display page', function() {
224234

235+
// https://docs.cypress.io/guides/references/migration-guide#Simulating-Pre-Test-Isolation-Behavior
236+
beforeEach(() => {
237+
cy.clearLocalStorage();
238+
cy.clearCookies();
239+
});
240+
225241
after(function(){
226242

227243
// Edit the higlass display back to draft status.

deploy/post_deploy_testing/cypress/e2e/09a_create_biosample.cy.js

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,11 @@ describe('Biosample create page', function () {
3939
cy.get('input#field_for_tags.form-control').focus().type('deleted_by_cypress_test').wait(100).end();
4040

4141
// Click Validate button
42-
cy.get(".action-buttons-container .btn")
43-
.within(function () {
44-
return cy.contains('Validate').click().end().wait(1000);
45-
}).end()
46-
//Click Submit button
47-
.get(".action-buttons-container .btn").within(function () {
48-
return cy.contains('Submit').click().end().wait(500);
49-
}).end()
50-
//Navigate new biosample data page
51-
.get(".action-buttons-container .btn").within(function () {
52-
return cy.contains('Skip').click().end();
53-
})
54-
.end()
55-
.get("h1.page-title").contains("Biosample").wait(3000).end(); // Await until are at Biosample page. Then wait 1s to ensure we have new context.
42+
cy.get(".action-buttons-container").as("editButtons");
43+
cy.get("@editButtons").find('button.btn').contains('Validate').click().end().wait(1000).end();
44+
cy.get("@editButtons").find('button.btn').contains('Submit').click().end().wait(500).end();
45+
cy.get("@editButtons").find('button.btn').contains('Skip').click().end();
46+
cy.get("h1.page-title").contains("Biosample").wait(3000).end(); // Await until are at Biosample page. Then wait 1s to ensure we have new context.
5647

5748
// Queue for deletion in subsequent test.
5849
cy.get('script[data-prop-name=context]').then(function($context){

deploy/post_deploy_testing/cypress/support/commands.js

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
2626

2727
import _ from 'underscore';
28-
var jwt = require('jsonwebtoken');
29-
import { Buffer } from 'buffer';
28+
const jose = require('jose');
3029
import { navUserAcctDropdownBtnSelector, navUserAcctLoginBtnSelector } from './variables';
3130

3231

@@ -86,6 +85,31 @@ const auth0UserIds = {
8685
'[email protected]': 'google-oauth2|104145819796576369116'
8786
};
8887

88+
89+
Cypress.Commands.add('signJWT', (auth0secret, email, sub) => {
90+
cy.request({
91+
'url' : '/auth0_config?format=json',
92+
'method' : 'GET',
93+
'headers' : { 'Accept': "application/json", 'Content-Type': "application/json; charset=UTF-8" },
94+
'followRedirect' : true
95+
}).then(function (resp) {
96+
if (resp.status && resp.status === 200) {
97+
const auth0Config = resp.body;
98+
const secret = new TextEncoder().encode(auth0secret);
99+
const jwt = new jose.SignJWT({ 'email': email, 'email_verified': true });
100+
const token = jwt
101+
.setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
102+
.setIssuedAt()
103+
.setIssuer(auth0Config.auth0Domain)
104+
.setExpirationTime('1h')
105+
.setAudience(auth0Config.auth0Client)
106+
.setSubject(sub)
107+
.sign(secret);
108+
return token;
109+
}
110+
});
111+
});
112+
89113
/**
90114
* This emulates login.js. Perhaps we should adjust login.js somewhat to match this better re: navigate.then(...) .
91115
*/
@@ -124,10 +148,8 @@ Cypress.Commands.add('login4DN', function(options = { 'useEnvToken' : true }){
124148
}).end();
125149
}
126150

127-
let jwt_token = null;
128-
129151
if (options.useEnvToken) {
130-
jwt_token = Cypress.env('JWT_TOKEN');
152+
const jwt_token = Cypress.env('JWT_TOKEN');
131153
console.log('ENV TOKEN', jwt_token);
132154
if (typeof jwt_token === 'string' && jwt_token) {
133155
console.log('Logging in with token');
@@ -138,35 +160,27 @@ Cypress.Commands.add('login4DN', function(options = { 'useEnvToken' : true }){
138160
// If no token, we try to generate/impersonate one ourselves
139161

140162
const email = options.email || options.user || Cypress.env('LOGIN_AS_USER') || '[email protected]';
141-
const auth0client = Cypress.env('Auth0Client');
142163
const auth0secret = Cypress.env('Auth0Secret');
143164

144-
if (!auth0client || !auth0secret) throw new Error('Cannot test login if no Auth0Client & Auth0Secret in ENV vars.');
165+
if (!auth0secret) throw new Error('Cannot test login if no Auth0Secret in ENV vars.');
145166

146167
Cypress.log({
147168
'name' : "Login 4DN",
148169
'message' : 'Attempting to impersonate-login for ' + email,
149170
'consoleProps' : ()=>{
150-
return { auth0client, auth0secret, email };
171+
return { auth0secret, email };
151172
}
152173
});
153174

154175
// Generate JWT
155-
const jwtPayload = {
156-
'email': email,
157-
'email_verified': true,
158-
'aud': auth0client,
159-
"iss": "https://hms-dbmi.auth0.com/",
160-
"sub": auth0UserIds[email] || ''
161-
};
162-
163-
jwt_token = jwt.sign(jwtPayload, Buffer.from(auth0secret, 'utf-8'));
164-
expect(jwt_token).to.have.length.greaterThan(0);
165-
Cypress.log({
166-
'name' : "Login 4DN",
167-
'message' : 'Generated own JWT with length ' + jwt_token.length,
176+
cy.signJWT(auth0secret, email, auth0UserIds[email] || '').then((token) => {
177+
expect(token).to.have.length.greaterThan(0);
178+
Cypress.log({
179+
'name': "Login 4DN",
180+
'message': 'Generated own JWT with length ' + token.length,
181+
});
182+
return performLogin(token);
168183
});
169-
return performLogin(jwt_token);
170184

171185
});
172186

0 commit comments

Comments
 (0)