Skip to content

Commit 3e6ac2d

Browse files
author
Joonatan Mäkinen
committed
Test/e2e tests december (merge commit)
Merge branch 'test/e2e-tests-december' into 'main' * Delete fixtures between tests * Add file download as part of e2e sharing test * Add test for direct archive download * Test direct file download via OPFS * Add test for archive download with service worker * Test service worker file download * Improve flaky logout command * Reset DB between tests. Reset deletes containers in swift and admin projects * Make cypress test formatting consistent * Update and reorder cypress commands * Refactor container e2e tests * Remove userInfo.cy.js old login tests, move missing to login.cy.js, refactor * Update browser tests * Check for error alert when adding a duplicate file for upload test. Unify quotation marks * Add testid to progress toast * Refactor cypress commands. Use file upload commands * Update and finish upload e2e tests. Use upload folder creation instead of deprecated upload folder search * Fix test to find a shared folder in a multi-page table * Update table sharing test, test upload to shared folder. Add share command. * Switch user instead of projects. Shorten wait time before toast * Update sharing tests, remove reliance on UI text, add project switching command * added download test * added commands * added tests * init Closes #952, #953, and #954 See merge request https://gitlab.ci.csc.fi/sds-dev/sd-connect/swift-browser-ui/-/merge_requests/236 Approved-by: Joonatan Mäkinen <[email protected]> Co-authored-by: Monika Radaviciute <[email protected]> Co-authored-by: Mariia <[email protected]> Merged by Joonatan Mäkinen <[email protected]>
2 parents 92a4d84 + aa5d6b1 commit 3e6ac2d

34 files changed

+1432
-869
lines changed

swift_browser_ui_frontend/cypress.config.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const { defineConfig } = require("cypress");
22
const { cloudPlugin } = require("cypress-cloud/plugin");
33
const { Client } = require("pg");
44
const { spawn } = require("node:child_process");
5+
const { rmdir, existsSync } = require("fs");
56

67
module.exports = defineConfig({
78
fixturesFolder: "../tests/cypress/fixtures",
@@ -50,19 +51,44 @@ module.exports = defineConfig({
5051

5152
return null;
5253
},
54+
extractArchive({ directory, archive }) {
55+
const cp = spawn("bash",
56+
["../tests/cypress/support/extractArchive.sh"],
57+
{env: { DIR: directory, ARCHIVE: archive }},
58+
);
59+
60+
cp.stderr.on("data", (data) => {
61+
console.error(`stderr: ${data}`);
62+
});
63+
return null;
64+
},
65+
deleteFolder(folder) {
66+
if (existsSync(folder)) {
67+
rmdir(folder, { recursive: true }, (err) => {
68+
if (err) console.error(err);
69+
});
70+
}
71+
return null;
72+
},
5373
});
5474
return cloudPlugin(on, config);
5575
},
5676
// baseUrl: "https://172.17.0.1:8081/",
57-
baseUrl: "https://sd-connect.dev:8000/",
77+
baseUrl: "https://sd-connect.dev:8081/",
5878

5979
specPattern: "../tests/cypress/integration/**/*.cy.{js,jsx,ts,tsx}",
6080
supportFile: "../tests/cypress/support/index.js",
81+
experimentalStudio: true,
82+
textFileLocation: "../tests/cypress/fixtures/text-files/",
83+
downloadsFolder: "../tests/cypress/fixtures/downloads/",
84+
trashAssetsBeforeRuns: true,
6185
},
6286
env: {
6387
username: "swift",
6488
password: "veryfast",
6589
wrongusername: "swif11t",
6690
wrongpassword: "very11fast",
91+
username2: "admin",
92+
password2: "superuser",
6793
},
6894
});

swift_browser_ui_frontend/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"name": "swift_browser_ui_frontend_npm",
33
"version": "2.0.1",
44
"private": true,
5-
"type": "module",
65
"scripts": {
76
"serve": "./build_wasm.sh && vite serve --mode development",
87
"build": "./build_wasm.sh && vite build --mode production",
@@ -30,6 +29,7 @@
3029
"luxon": "^3.4.4",
3130
"rxjs": "^7.8.1",
3231
"sass": "^1.77.4",
32+
"spark-md5": "^3.0.2",
3333
"vite": "^5.2.12",
3434
"vue": "^3.4.27",
3535
"vue-i18n": "^9.13.1",

swift_browser_ui_frontend/pnpm-lock.yaml

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

swift_browser_ui_frontend/src/common/socket.js

+47-26
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ export default class UploadSocket {
225225
}
226226
}
227227

228+
228229
// Get headers for download
229230
async getHeaders(id, container, fileList, pubkey, owner, ownerName) {
230231
let headers = {};
@@ -401,6 +402,7 @@ export default class UploadSocket {
401402
container,
402403
objects,
403404
owner = "",
405+
test = false,
404406
) {
405407

406408
//get random id
@@ -416,25 +418,34 @@ export default class UploadSocket {
416418
// Download directly into the file if available.
417419
// Otherwise, use streaming + ServiceWorker.
418420
if (!this.useServiceWorker) {
421+
const fileName = objects[0].replace(".c4gh", "");
422+
423+
if (test) {
424+
//OPFS root for direct download e2e testing
425+
const testDirHandle = await navigator.storage.getDirectory();
426+
fileHandle =
427+
await testDirHandle.getFileHandle(fileName, { create: true });
428+
}
429+
else {
419430
// Match the file identifier
420-
const fident = objects[0].replace(".c4gh", "")
421-
.match(/(?<!^)\.[^.]{1,}$/g);
422-
const opts = {
423-
suggestedName: objects[0].split("/").at(-1).replace(".c4gh", ""),
424-
};
425-
426-
if (fident) {
427-
opts.types = [
428-
{
429-
description: "Generic file",
430-
accept: {
431-
"application/octet-stream": [fident],
431+
const fident = objects[0].replace(".c4gh", "")
432+
.match(/(?<!^)\.[^.]{1,}$/g);
433+
const opts = {
434+
suggestedName: fileName,
435+
};
436+
437+
if (fident) {
438+
opts.types = [
439+
{
440+
description: "Generic file",
441+
accept: {
442+
"application/octet-stream": [fident],
443+
},
432444
},
433-
},
434-
];
445+
];
446+
}
447+
fileHandle = await window.showSaveFilePicker(opts);
435448
}
436-
fileHandle = await window.showSaveFilePicker(opts);
437-
438449
this.downWorker.postMessage({
439450
command: "downloadFile",
440451
id: sessionId,
@@ -443,6 +454,7 @@ export default class UploadSocket {
443454
handle: fileHandle,
444455
owner: owner,
445456
ownerName: ownerName,
457+
test: test,
446458
});
447459
} else {
448460
if (DEV) {
@@ -463,17 +475,25 @@ export default class UploadSocket {
463475
// Download directly into the archive if available.
464476
// Otherwise, use streaming + ServiceWorker.
465477
if (!this.useServiceWorker) {
466-
fileHandle = await window.showSaveFilePicker({
467-
suggestedName: `${container}_download.tar`,
468-
types: [
469-
{
470-
description: "Tar archive (uncompressed)",
471-
accept: {
472-
"application/x-tar": [".tar"],
478+
const fileName = `${container}_download.tar`;
479+
if (test) {
480+
//OPFS root for direct download e2e testing
481+
const testDirHandle = await navigator.storage.getDirectory();
482+
fileHandle =
483+
await testDirHandle.getFileHandle(fileName, { create: true });
484+
} else {
485+
fileHandle = await window.showSaveFilePicker({
486+
suggestedName: fileName,
487+
types: [
488+
{
489+
description: "Tar archive (uncompressed)",
490+
accept: {
491+
"application/x-tar": [".tar"],
492+
},
473493
},
474-
},
475-
],
476-
});
494+
],
495+
});
496+
}
477497
this.downWorker.postMessage({
478498
command: "downloadFiles",
479499
id: sessionId,
@@ -482,6 +502,7 @@ export default class UploadSocket {
482502
handle: fileHandle,
483503
owner: owner,
484504
ownerName: ownerName,
505+
test: test,
485506
});
486507
} else {
487508
navigator.serviceWorker.ready.then(reg => {

swift_browser_ui_frontend/src/components/BrowserMainNavbar.vue

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<c-sidenavigationitem
5050
v-for="item of navigationMenuItems"
5151
:key="item.title"
52+
:data-testid="item.testid + '-mobile'"
5253
>
5354
<div slot="main">
5455
<span :class="'mdi ' + item.icon" />
@@ -64,7 +65,7 @@
6465
:key="subItem.title"
6566
:href="subItem.href"
6667
:target="subItem.href && '_blank'"
67-
:data-testid="subItem.testid"
68+
:data-testid="subItem.testid + '-mobile'"
6869
@click="() => {
6970
(subItem.route || subItem.href) && handleItemRoute(subItem);
7071
subItem.action && subItem.action();
@@ -260,7 +261,7 @@ c-menu {
260261
}
261262
262263
@media screen and (min-width: 768px) {
263-
c-navigationbutton {
264+
c-navigationbutton, c-sidenavigation {
264265
display: none;
265266
}
266267
}

swift_browser_ui_frontend/src/components/CObjectTable.vue

+14-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
because csc-ui wont recognise it otherwise. -->
55
<c-data-table
66
id="obj-table"
7+
data-testid="object-table"
78
:data.prop="objects"
89
:headers.prop="hideTags ?
910
headers.filter(header => header.key !== 'tags'): headers"
@@ -229,13 +230,14 @@ export default {
229230
component: {
230231
tag: "c-button",
231232
params: {
233+
testid: "download-object",
232234
text: true,
233235
size: "small",
234236
title: "Download",
235237
path: mdiTrayArrowDown,
236-
onClick: () => {
238+
onClick: ({ event }) => {
237239
item.name.match(".c4gh") || item?.subfolder
238-
? this.beginDownload(item)
240+
? this.beginDownload(item, event.isTrusted)
239241
: this.navDownload(item.url);
240242
},
241243
disabled: this.owner != undefined &&
@@ -248,6 +250,7 @@ export default {
248250
component: {
249251
tag: "c-button",
250252
params: {
253+
testid: "edit-object-tags",
251254
text: true,
252255
size: "small",
253256
title: "Edit tags",
@@ -269,6 +272,7 @@ export default {
269272
component: {
270273
tag: "c-button",
271274
params: {
275+
testid: "delete-object",
272276
text: true,
273277
size: "small",
274278
title: "Delete object",
@@ -411,7 +415,12 @@ export default {
411415
this.$emit("selected-rows", event.detail);
412416
}
413417
},
414-
beginDownload(object) {
418+
beginDownload(object, eventTrusted) {
419+
//add test param to test direct downloads
420+
//by using origin private file system (OPFS)
421+
//automated testing creates untrusted events
422+
const test = eventTrusted === undefined ? false: !eventTrusted;
423+
415424
if (object?.subfolder) {
416425
const subfolderFiles = this
417426
.objs
@@ -424,6 +433,7 @@ export default {
424433
this.$route.params.container,
425434
subfolderFiles,
426435
this.$route.params.owner ? this.$route.params.owner : "",
436+
test,
427437
).then(() => {
428438
if (DEV) console.log(`Started downloading subfolder ${object.name}`);
429439
}).catch(() => {
@@ -434,6 +444,7 @@ export default {
434444
this.$route.params.container,
435445
[object.name],
436446
this.$route.params.owner ? this.$route.params.owner : "",
447+
test,
437448
).then(() => {
438449
if (DEV) console.log(`Started downloading object ${object.name}`);
439450
}).catch(() => {

swift_browser_ui_frontend/src/components/CUploadButton.vue

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Inspired by https://github.com/buefy/buefy/blob/3b3ae60e448ddfd669f20570d40812fd
1111
</c-button>
1212
<input
1313
ref="input"
14+
data-testid="select-files-input"
1415
:value="modelValue"
1516
type="file"
1617
multiple

swift_browser_ui_frontend/src/components/ContainerTable.vue

+12-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
because csc-ui wont recognise it otherwise. -->
44
<c-data-table
55
id="container-table"
6+
data-testid="container-table"
67
:data.prop="containers"
78
:headers.prop="hideTags ?
89
headers.filter(header => header.key !== 'tags'): headers"
@@ -276,13 +277,15 @@ export default {
276277
component: {
277278
tag: "c-button",
278279
params: {
280+
testid: "download-container",
279281
text: true,
280282
size: "small",
281283
title: this.$t("message.download.download"),
282-
onClick: () => {
284+
onClick: ({ event }) => {
283285
this.beginDownload(
284286
item.name,
285287
item.owner ? item.owner : "",
288+
event.isTrusted,
286289
);
287290
},
288291
target: "_blank",
@@ -298,6 +301,7 @@ export default {
298301
component: {
299302
tag: "c-button",
300303
params: {
304+
testid: "share-container",
301305
text: true,
302306
size: "small",
303307
title: this.$t("message.share.share"),
@@ -510,11 +514,17 @@ export default {
510514
this.paginationOptions.itemCount - 1,
511515
});
512516
},
513-
beginDownload(container, owner) {
517+
beginDownload(container, owner, eventTrusted) {
518+
//add test param to test direct downloads
519+
//by using origin private file system (OPFS)
520+
//automated testing creates untrusted events
521+
const test = eventTrusted === undefined ? false : !eventTrusted;
522+
514523
this.$store.state.socket.addDownload(
515524
container,
516525
[],
517526
owner,
527+
test,
518528
).then(() => {
519529
if (DEV) console.log(`Started downloading all objects from container ${container}`);
520530
}).catch(() => {

swift_browser_ui_frontend/src/components/Containers.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<c-menu
2020
:key="optionsKey"
2121
:items.prop="tableOptions"
22-
options-testid="table-options-selector"
22+
data-testid="table-options-selector"
2323
>
2424
<span class="menu-active display-options-menu">
2525
<i class="mdi mdi-tune" />

swift_browser_ui_frontend/src/components/CreateFolderModal.vue

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<c-card
33
ref="createFolderContainer"
44
class="add-folder"
5+
data-testid="create-folder-modal"
56
@keydown="handleKeyDown"
67
>
78
<div
@@ -66,6 +67,7 @@
6667
<c-button
6768
outlined
6869
size="large"
70+
data-testid="cancel-save-folder"
6971
@click="toggleCreateFolderModal(false)"
7072
@keyup.enter="toggleCreateFolderModal(true)"
7173
>

swift_browser_ui_frontend/src/components/DeleteModal.vue

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
</c-button>
3333
<c-button
3434
id="delete-objs-btn"
35+
data-testid="confirm-delete-objects"
3536
@click="deleteObjects()"
3637
@keyup.enter="deleteObjects()"
3738
>

0 commit comments

Comments
 (0)