|
21 | 21 | * |
22 | 22 | */ |
23 | 23 |
|
24 | | -import { randHash } from "../utils/"; |
| 24 | +import { randHash } from '../utils/' |
25 | 25 |
|
26 | 26 | /** |
27 | 27 | * Make a name aimed to break the viewer in case of escaping errors |
28 | 28 | * |
29 | | - * @param {String} realName |
| 29 | + * @param {String} realName original name of the file |
30 | 30 | * @returns {String} a name for the file to be uploaded as |
31 | 31 | */ |
32 | 32 | function naughtyFileName(realName) { |
33 | | - const ext = realName.split(".").pop(); |
| 33 | + const ext = realName.split('.').pop() |
34 | 34 | return ( |
35 | | - "~⛰️ shot of a ${big} mountain`, " + |
36 | | - "realy #1's " + |
37 | | - '" #_+="%2520%27%22%60%25%21%23 was this called ' + |
38 | | - realName + |
39 | | - "in the" + |
40 | | - "☁️" + |
41 | | - "👩💻" + |
42 | | - "? :* ." + |
43 | | - ext.toUpperCase() |
44 | | - ); |
| 35 | + '~⛰️ shot of a ${big} mountain`, ' |
| 36 | + + "realy #1's " |
| 37 | + + '" #_+="%2520%27%22%60%25%21%23 was this called ' |
| 38 | + + realName |
| 39 | + + 'in % the' |
| 40 | + + '☁️' |
| 41 | + + '👩💻' |
| 42 | + + '? :* .' |
| 43 | + + ext.toUpperCase() |
| 44 | + ) |
45 | 45 | } |
46 | 46 |
|
47 | | -for (let [file, type] of [ |
48 | | - ["audio.mp3", "audio/mpeg"], |
49 | | - ["audio.ogg", "audio/mpeg"], |
50 | | - ["audio.ogg", "audio/ogg"], |
51 | | - ["image1.jpg", "image/jpeg"], |
52 | | - ["image.gif", "image/gif"], |
53 | | - ["image.heic", "image/heic"], |
54 | | - ["image.png", "image/png"], |
55 | | - ["image-small.png", "image/png"], |
56 | | - ["image.svg", "image/svg"], |
57 | | - ["image.webp", "image/webp"], |
58 | | - ["video1.mp4", "video/mp4"], |
59 | | - ["video.mkv", "video/mkv"], |
60 | | - ["video.ogv", "video/ogv"], |
61 | | - ["video.webm", "video/webm"], |
| 47 | +// Make this test fail faster |
| 48 | +let failsLeft = 5 |
| 49 | +Cypress.on('fail', (error, runnable) => { |
| 50 | + failsLeft-- |
| 51 | + throw error // throw error to have test still fail |
| 52 | +}) |
| 53 | + |
| 54 | +for (const [file, type] of [ |
| 55 | + ['audio.mp3', 'audio/mpeg'], |
| 56 | + ['audio.ogg', 'audio/mpeg'], |
| 57 | + ['audio.ogg', 'audio/ogg'], |
| 58 | + ['image-small.png', 'image/png'], |
| 59 | + ['image.gif', 'image/gif'], |
| 60 | + ['image.heic', 'image/heic'], |
| 61 | + ['image.png', 'image/png'], |
| 62 | + ['image.svg', 'image/svg'], |
| 63 | + ['image.webp', 'image/webp'], |
| 64 | + ['image1.jpg', 'image/jpeg'], |
| 65 | + ['video.mkv', 'video/mkv'], |
| 66 | + ['video.ogv', 'video/ogv'], |
| 67 | + ['video.webm', 'video/webm'], |
| 68 | + ['video1.mp4', 'video/mp4'], |
62 | 69 | ]) { |
63 | | - const placedName = naughtyFileName(file); |
| 70 | + const placedName = naughtyFileName(file) |
64 | 71 |
|
65 | 72 | // We'll escape all the characters in the name to match it with css |
66 | | - const placedNameCss = CSS.escape(placedName); |
| 73 | + const placedNameCss = CSS.escape(placedName) |
67 | 74 |
|
68 | 75 | // fresh user for each file |
69 | | - const randUser = randHash() + "@-" + randHash(); // @ is allowed, so use it |
| 76 | + const randUser = randHash() + '@-' + randHash() // @ is allowed, so use it |
70 | 77 |
|
71 | | - const folderName = |
72 | | - 'Nextcloud "%27%22%60%25%21%23" >`⛰️<' + file + "><` e*'rocks!#?#%~"; |
| 78 | + const folderName |
| 79 | + = 'Nextcloud "%27%22%60%25%21%23" >`⛰️<' + file + "><` e*'rocks!#?#%~" |
| 80 | + |
| 81 | + describe(`Open ${file} in viewer with a naughty name`, function() { |
| 82 | + before(function() { |
| 83 | + // fail fast |
| 84 | + if (failsLeft < 0) { |
| 85 | + throw new Error('Too many previous tests failed') |
| 86 | + } |
73 | 87 |
|
74 | | - describe(`Open ${file} in viewer with a naughty name`, function () { |
75 | | - before(function () { |
76 | 88 | // Init user |
77 | | - cy.nextcloudCreateUser(randUser, "password"); |
78 | | - cy.login(randUser, "password"); |
| 89 | + cy.nextcloudCreateUser(randUser, 'password') |
| 90 | + cy.login(randUser, 'password') |
79 | 91 |
|
80 | 92 | // Upload test files |
81 | | - cy.createFolder(folderName); |
82 | | - cy.uploadFile(file, type, "/" + folderName, placedName); |
83 | | - cy.visit("/apps/files"); |
| 93 | + cy.createFolder(folderName) |
| 94 | + cy.uploadFile(file, type, '/' + folderName, placedName) |
| 95 | + cy.visit('/apps/files') |
84 | 96 |
|
85 | 97 | // wait a bit for things to be settled |
86 | | - cy.wait(1000); |
87 | | - cy.openFile(folderName); |
88 | | - cy.wait(1000); |
89 | | - }); |
90 | | - after(function () { |
| 98 | + cy.wait(1000) |
| 99 | + cy.openFile(folderName) |
| 100 | + cy.wait(1000) |
| 101 | + }) |
| 102 | + after(function() { |
91 | 103 | // no need to log out we do this in the test to check the public link |
92 | | - }); |
93 | | - |
94 | | - it(`See ${file} as ${placedName} in the list`, function () { |
| 104 | + }) |
| 105 | + |
| 106 | + function noLoadingAnimation() { |
| 107 | + cy.get('body > .viewer', { timeout: 10000 }) |
| 108 | + .should('be.visible') |
| 109 | + .and('have.class', 'modal-mask') |
| 110 | + .and('not.have.class', 'icon-loading') |
| 111 | + } |
| 112 | + |
| 113 | + function menuOk() { |
| 114 | + cy.get('body > .viewer .icon-error').should('not.exist') |
| 115 | + cy.get('body > .viewer .modal-title').should('contain', placedName) |
| 116 | + cy.get('body > .viewer .modal-header button.icon-close').should( |
| 117 | + 'be.visible' |
| 118 | + ) |
| 119 | + } |
| 120 | + |
| 121 | + function arrowsOK() { |
| 122 | + cy.get('body > .viewer a.prev').should('not.be.visible') |
| 123 | + cy.get('body > .viewer a.next').should('not.be.visible') |
| 124 | + } |
| 125 | + |
| 126 | + it(`See ${file} as ${placedName} in the list`, function() { |
95 | 127 | cy.get(`#fileList tr[data-file="${placedNameCss}"]`, { |
96 | 128 | timeout: 10000, |
97 | | - }).should("contain", placedName); |
98 | | - }); |
99 | | - |
100 | | - it("Open the viewer on file click", function () { |
101 | | - cy.openFile(placedName); |
102 | | - cy.get("body > .viewer").should("be.visible"); |
103 | | - }); |
104 | | - |
105 | | - it("Does not see a loading animation", function () { |
106 | | - cy.get("body > .viewer", { timeout: 10000 }) |
107 | | - .should("be.visible") |
108 | | - .and("have.class", "modal-mask") |
109 | | - .and("not.have.class", "icon-loading"); |
110 | | - }); |
111 | | - |
112 | | - it("See the menu icon and title on the viewer header", function () { |
113 | | - cy.get("body > .viewer .modal-title").should("contain", placedName); |
114 | | - cy.get( |
115 | | - "body > .viewer .modal-header button.action-item__menutoggle" |
116 | | - ).should("be.visible"); |
117 | | - cy.get("body > .viewer .modal-header button.icon-close").should( |
118 | | - "be.visible" |
119 | | - ); |
120 | | - }); |
121 | | - |
122 | | - it("Does not see navigation arrows", function () { |
123 | | - cy.get("body > .viewer a.prev").should("not.be.visible"); |
124 | | - cy.get("body > .viewer a.next").should("not.be.visible"); |
125 | | - }); |
126 | | - |
127 | | - it("Share the folder with a share link and access the share link", function () { |
| 129 | + }).should('contain', placedName) |
| 130 | + }) |
| 131 | + |
| 132 | + it('Open the viewer on file click', function() { |
| 133 | + cy.openFile(placedName) |
| 134 | + cy.get('body > .viewer').should('be.visible') |
| 135 | + }) |
| 136 | + |
| 137 | + it('Does not see a loading animation', noLoadingAnimation) |
| 138 | + it('See the menu icon and title on the viewer header', menuOk) |
| 139 | + it('Does not see navigation arrows', arrowsOK) |
| 140 | + |
| 141 | + it('Share the folder with a share link and access the share link', function() { |
128 | 142 | cy.createLinkShare(folderName).then((token) => { |
129 | | - cy.logout(); |
130 | | - cy.visit(`/s/${token}`); |
131 | | - }); |
132 | | - }); |
133 | | - |
134 | | - it("Open the viewer on file click (public)", function () { |
135 | | - cy.openFile(placedName); |
136 | | - cy.get("body > .viewer").should("be.visible"); |
137 | | - }); |
138 | | - |
139 | | - it("Does not see a loading animation (public)", function () { |
140 | | - cy.get("body > .viewer", { timeout: 10000 }) |
141 | | - .should("be.visible") |
142 | | - .and("have.class", "modal-mask") |
143 | | - .and("not.have.class", "icon-loading"); |
144 | | - }); |
145 | | - |
146 | | - it("See the menu icon and title on the viewer header (public)", function () { |
147 | | - cy.get("body > .viewer .modal-title").should("contain", placedName); |
148 | | - cy.get("body > .viewer .modal-header button.icon-close").should( |
149 | | - "be.visible" |
150 | | - ); |
151 | | - }); |
152 | | - |
153 | | - it("Does not see navigation arrows (public)", function () { |
154 | | - cy.get("body > .viewer a.prev").should("not.be.visible"); |
155 | | - cy.get("body > .viewer a.next").should("not.be.visible"); |
156 | | - }); |
157 | | - }); |
| 143 | + cy.logout() |
| 144 | + cy.visit(`/s/${token}`) |
| 145 | + }) |
| 146 | + }) |
| 147 | + |
| 148 | + it('Open the viewer on file click (public)', function() { |
| 149 | + cy.openFile(placedName) |
| 150 | + cy.get('body > .viewer').should('be.visible') |
| 151 | + }) |
| 152 | + |
| 153 | + it('Does not see a loading animation (public)', noLoadingAnimation) |
| 154 | + it('See the menu icon and title on the viewer header (public)', menuOk) |
| 155 | + it('Does not see navigation arrows (public)', arrowsOK) |
| 156 | + }) |
158 | 157 | } |
0 commit comments