Skip to content

Commit ea0b4ec

Browse files
author
Zé Bateira
authored
chore: add firefox testing to ci build command (#565)
1 parent 2471e53 commit ea0b4ec

File tree

17 files changed

+87
-53
lines changed

17 files changed

+87
-53
lines changed

DEVELOPING_TUTORIALS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ const run = async (files) => {
590590
Behind the scenes, the uploaded files have been saved as `window.uploadedFiles` for use both in your user's code and in your own validation. In your `validate` function, we recommend saving the files to a variable and allowing for the fact that they may not be present. For example:
591591

592592
```js
593-
const uploadedFiles = window.uploadedFiles || false
593+
const uploadedFiles = window.uploadedFiles || []
594594
```
595595

596596
Remember that these files are stored as browser file objects. Reference the [Files documentation](https://developer.mozilla.org/en-US/docs/Web/API/File#Properties) to see what properties are available to both you and the user, including `name` and `type`.

cypress.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"baseUrl": "http://localhost:3000",
3-
"responseTimeout": 60000,
4-
"defaultCommandTimeout": 60000,
3+
"defaultCommandTimeout": 30000,
54
"video": false
65
}

cypress/integration/tutorials.spec.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ function testMultipleChoiceOptions (tutorialId, lessonNr) {
201201
const lesson = tutorials[tutorialId].lessons[parseInt(lessonNr) - 1]
202202
const choices = lesson.logic.choices
203203
const correctChoiceIndex = choices.findIndex(choice => choice.correct === true)
204+
204205
it(`displays right number of choices lesson ${lessonNr} and displays as not yet started`, function () {
205206
cy.visit(`/${tutorialName}/${lessonNr}`)
206207
cy.get('[data-cy=choice]').should('have.length', choices.length)
@@ -209,28 +210,33 @@ function testMultipleChoiceOptions (tutorialId, lessonNr) {
209210
cy.get(`[data-cy=progress-not-yet-started]`).should('be.visible')
210211
cy.get(`[data-cy=progress-icon-not-yet-started]`).should('be.visible')
211212
})
213+
212214
function testChoice (choice, index) {
213215
let choiceType = index === correctChoiceIndex ? 'RIGHT' : 'WRONG'
214216
let correctOutput = index === correctChoiceIndex ? 'output-success' : 'output-fail'
215217
let incorrectOutput = index === correctChoiceIndex ? 'output-fail' : 'output-success'
216218
let correctButton = index === correctChoiceIndex ? 'not.be.disabled' : 'be.disabled'
217219
let correctProgress = index === correctChoiceIndex ? 'passed' : 'in-progress'
220+
218221
describe(`${choiceType} choice ${index}`, function () {
219222
it(`shows correct completion status and button state`, function () {
220223
cy.get('[data-cy=choice]').eq(index).click()
221224
cy.get(`[data-cy=progress-${correctProgress}]`).should('be.visible')
222225
cy.get(`[data-cy=progress-icon-${correctProgress}]`).should('be.visible')
223226
cy.get('[data-cy=next-lesson-mult-choice]').should(correctButton)
224227
})
228+
225229
it(`displays answer correctly`, function () {
226230
cy.get('[data-cy=choice]').eq(index).should('contain', parseTextForMarkdown(choice.answer))
227231
})
232+
228233
it(`displays feedback correctly`, function () {
229234
cy.get(`[data-cy=${incorrectOutput}]`).should('not.exist')
230235
cy.get(`[data-cy=${correctOutput}]`).should('contain', parseTextForMarkdown(choice.feedback))
231236
})
232237
})
233238
}
239+
234240
// test correct answer first to ensure passed status will be cleared afterward
235241
testChoice(choices[correctChoiceIndex], correctChoiceIndex)
236242
// test all incorrect answers
@@ -372,19 +378,21 @@ function advanceThroughLessons (tutorialId) {
372378
function uploadSingleFile () {
373379
it(`uploads a single file`, function () {
374380
cy.fixture(fixtures.png).then(fileContent => {
375-
cy.get('[data-cy=file-upload]').upload({ fileContent, fileName: fixtures.png, mimeType: 'image/png' })
381+
cy.get('[data-cy=file-upload]').attachFile({ fileContent, fileName: fixtures.png, mimeType: 'image/png' })
376382
})
377383
})
378384
}
379385
function uploadMultipleFiles () {
380386
it(`uploads 2 files`, function () {
381-
cy.fixture(fixtures.json, 'base64').then(exampleJson => {
382-
cy.fixture(fixtures.png, 'base64').then(faviconPng => {
387+
cy.fixture(fixtures.json).then(exampleJson => {
388+
cy.fixture(fixtures.png).then(faviconPng => {
383389
const files = [
384390
{ fileName: fixtures.json, fileContent: exampleJson, mimeType: 'application/json' },
385391
{ fileName: fixtures.png, fileContent: faviconPng, mimeType: 'image/png' }
386392
]
387-
cy.get('[data-cy=file-upload]').upload(files, { uploadType: 'input' })
393+
cy.get('[data-cy=file-upload]')
394+
.attachFile(files[0], { uploadType: 'input' })
395+
.attachFile(files[1], { uploadType: 'input' })
388396
})
389397
})
390398
})
@@ -536,7 +544,7 @@ describe('SHOULD ADVANCE LESSONS WITH TRAILING SLASHES', () => {
536544
cy.get('[data-cy=code-editor-ready]').should('be.visible') // wait for editor to be updated
537545

538546
cy.fixture(fixtures.png).then(fileContent => {
539-
cy.get('[data-cy=file-upload]').upload({ fileContent, fileName: fixtures.png, mimeType: 'image/png' })
547+
cy.get('[data-cy=file-upload]').attachFile({ fileContent, fileName: fixtures.png, mimeType: 'image/png' })
540548
})
541549
cy.get(`[data-cy=next-lesson-code]`).should('not.be.visible')
542550
cy.get('[data-cy=replace-with-solution]').click({ force: true })

package-lock.json

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

package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
"build:docs": "npm-run-all build:docs:design build:docs:develop",
1010
"build:docs:design": "markdown-toc -i DESIGNING_TUTORIALS.md",
1111
"build:docs:develop": "markdown-toc -i DEVELOPING_TUTORIALS.md",
12-
"build:fleek": "npm ci && npm run sitemap && npm run scripts:build:data -- --dry-run=false && npm run test:jest && npm run build && start-server-and-test cy:serve http://localhost:3000 cy:run",
12+
"build:fleek": "npm ci && npm run sitemap && npm run scripts:build:data -- --dry-run=false && npm run test:jest && npm run build && npm run cy:run:ci",
1313
"cy:open": "cypress open",
1414
"cy:run": "cypress run --browser chrome",
15+
"cy:run:ci": "start-server-and-test cy:serve http://localhost:3000 \"cypress run --browser chrome\" && start-server-and-test cy:serve http://localhost:3000 \"cypress run --browser firefox\"",
1516
"cy:serve": "serve -l 3000 dist",
1617
"install-protowizard": "npm i ./ -g",
1718
"scripts:build:data": "node scripts/commands/build-data",
@@ -63,8 +64,8 @@
6364
"@vue/cli-service": "^3.12.1",
6465
"babel-eslint": "^8.2.6",
6566
"cli-table": "^0.3.1",
66-
"cypress": "^5.4.0",
67-
"cypress-file-upload": "^3.5.3",
67+
"cypress": "^5.5.0",
68+
"cypress-file-upload": "^4.1.1",
6869
"del": "^5.1.0",
6970
"dotenv": "^8.2.0",
7071
"eslint": "^5.16.0",
@@ -132,4 +133,4 @@
132133
}
133134
},
134135
"license": "Apache-2.0 AND MIT"
135-
}
136+
}

src/components/FileLesson.vue

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ export default {
4343
let elem = document.querySelector('input#file')
4444
elem.click()
4545
},
46+
onFilesReset: function () {
47+
let elem = document.querySelector('input#file')
48+
elem.value = ''
49+
delete elem.files
50+
},
4651
onFiles: function (files) {
4752
this.uploadedFiles = files
4853
window.uploadedFiles = files

src/components/FileUpload.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
<div class="f5 fw7 mt4 mb2">
44
Step 1: Upload files
55
<span class="pl1">
6-
<img v-if="uploadedFiles" src="../static/images/complete.svg" alt="complete" style="height: 1.2rem;" class="v-mid" />
6+
<img v-if="uploadedFiles.length" src="../static/images/complete.svg" alt="complete" style="height: 1.2rem;" class="v-mid" />
77
</span>
88
</div>
99
<input type="file" multiple id="file" class="dn" data-cy="file-upload"/>
10-
<div v-if="!uploadedFiles"
10+
<div v-if="uploadedFiles.length === 0"
1111
@click="onFileClick" @drop="onFileDrop"
1212
@dragenter="dragging=true" @dragend="dragging=false" @dragleave="dragging=false" @dragover.prevent
1313
class="dropfile mb2 pa2 w-100 br3 shadow-4 bg-white color-navy" :class="{dragging: dragging}">
@@ -44,7 +44,7 @@ export default {
4444
onFileClick: Function,
4545
onFileDrop: Function,
4646
resetFileUpload: Function,
47-
uploadedFiles: [Boolean, Array]
47+
uploadedFiles: Array
4848
},
4949
data: self => {
5050
return {

src/components/Lesson.vue

+4-3
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ export default {
254254
editorReady: false,
255255
isFileLesson: self.isFileLesson,
256256
isMultipleChoiceLesson: self.isMultipleChoiceLesson,
257-
uploadedFiles: window.uploadedFiles || false,
257+
uploadedFiles: window.uploadedFiles || [],
258258
choice: localStorage[self.cacheKey] || '',
259259
cachedChoice: !!localStorage['cached' + routePath],
260260
output: self.output,
@@ -364,7 +364,7 @@ export default {
364364
365365
const code = this.editor.getValue()
366366
367-
if (this.isFileLesson && this.uploadedFiles === false && auto === true) {
367+
if (this.isFileLesson && this.uploadedFiles.length === 0 && auto === true) {
368368
this.showUploadInfo = true
369369
this.isSubmitting = false
370370
return
@@ -491,7 +491,8 @@ export default {
491491
countly.trackEvent(countly.events.CODE_RESET, this.trackingData)
492492
},
493493
resetFileUpload: function () {
494-
this.uploadedFiles = false
494+
this.uploadedFiles = []
495+
this.onFilesReset()
495496
delete this.output.test
496497
},
497498
clearPassed: function () {

src/components/Validator.vue

+7-7
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
</div>
1313
<div v-else-if="lessonPassed && !isSubmitting">
1414
<span class="disabled-btn-wrapper">
15-
<span v-if="isFileLesson && !uploadedFiles" class="mr2 red lh-copy o-0" data-cy="need-new-files-msg">
15+
<span v-if="isFileLesson && uploadedFiles.length === 0" class="mr2 red lh-copy o-0" data-cy="need-new-files-msg">
1616
You must upload a file before submitting.
1717
</span>
18-
<Button v-if="(isFileLesson && !output) || (isFileLesson && !uploadedFiles)"
19-
:disabled="!uploadedFiles"
18+
<Button v-if="(isFileLesson && !output) || (isFileLesson && uploadedFiles.length ===0)"
19+
:disabled="uploadedFiles.length === 0"
2020
:click="run"
2121
class="mr2 bg-navy white"
2222
style="minWidth: 90px"
@@ -32,14 +32,14 @@
3232
/>
3333
</div>
3434
<div v-else>
35-
<span v-if="(isFileLesson && !uploadedFiles) || isSubmitting" class="disabled-btn-wrapper">
36-
<span v-if="isFileLesson && !uploadedFiles" class="mr2 red lh-copy o-0" data-cy="need-files-msg">
35+
<span v-if="(isFileLesson && uploadedFiles.length === 0) || isSubmitting" class="disabled-btn-wrapper">
36+
<span v-if="isFileLesson && uploadedFiles.length === 0" class="mr2 red lh-copy o-0" data-cy="need-files-msg">
3737
You must upload a file before submitting.
3838
</span>
3939
<Button
4040
:click="next"
4141
:loading="isSubmitting"
42-
:disabled="isFileLesson && !uploadedFiles"
42+
:disabled="isFileLesson && uploadedFiles.length === 0"
4343
class="bg-navy white"
4444
data-cy="submit-disabled"
4545
text="Submit"
@@ -111,7 +111,7 @@ export default {
111111
challenge: String,
112112
isFileLesson: Boolean,
113113
isMultipleChoiceLesson: Boolean,
114-
uploadedFiles: [Boolean, Array],
114+
uploadedFiles: Array,
115115
lessonPassed: Boolean,
116116
output: Object,
117117
isResources: Boolean,

src/tutorials/0004-mutable-file-system/04.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const validate = async (result, ipfs) => {
4646
}
4747
}
4848

49-
if (uploadedFiles === false) {
49+
if (uploadedFiles.length === 0) {
5050
// Shouldn't happen because you can't hit submit without uploading files
5151
return { fail: 'Oops! You forgot to upload files to work with :(' }
5252
}

src/tutorials/0004-mutable-file-system/05.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const validate = async (result, ipfs) => {
1010
let directoryContentsMatch = JSON.stringify(result) === JSON.stringify(expected)
1111

1212
// Confirm the right files were added to IPFS (should be unless they tweaked the default code)
13-
let uploadedFiles = window.uploadedFiles || false
13+
let uploadedFiles = window.uploadedFiles || []
1414
let uploadedFilenames = uploadedFiles.map(file => file.name.toString()).sort()
1515
let ipfsFilenames = expected.map(file => file.name.toString()).sort()
1616
let itemsMatch = JSON.stringify(ipfsFilenames) === JSON.stringify(uploadedFilenames)
@@ -19,7 +19,7 @@ const validate = async (result, ipfs) => {
1919

2020
if (!result) {
2121
return { fail: 'Oops, you forgot to return a result. Did you accidentally delete `return directoryContents`?' }
22-
} else if (uploadedFiles === false) {
22+
} else if (uploadedFiles.length === 0) {
2323
// shouldn't happen because you can't hit submit without uploading files
2424
return { fail: 'Oops! You forgot to upload files to work with :(' }
2525
} else if (expected.length === 0) {

src/tutorials/0004-mutable-file-system/07.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ const validate = async (result, ipfs) => {
4242

4343
/** CHECK FOR CORRECT FILENAMES **/
4444

45-
let uploadedFiles = window.uploadedFiles || false
45+
let uploadedFiles = window.uploadedFiles || []
4646
let resultSorted = null
4747
let expectedSorted = null
4848
let contentsMatch = null
4949

5050
if (Array.isArray(result)) {
5151
resultSorted = result.map(file => file.name.toString()).sort()
52-
if (uploadedFiles) {
52+
if (uploadedFiles.length) {
5353
let expected = uploadedFiles.map(file => file.name.toString())
5454
expected.push('some')
5555
expectedSorted = expected.sort()
@@ -88,7 +88,7 @@ const validate = async (result, ipfs) => {
8888
logDesc: 'Here\'s what your `ls` command shows' + returnedDirectoryMsg + ':',
8989
log: result.map(utils.format.ipfsObject)
9090
}
91-
} else if (uploadedFiles === false) {
91+
} else if (uploadedFiles.length === 0) {
9292
// shouldn't happen because you can't hit submit without uploading files
9393
return {fail: 'Oops! You forgot to upload files to work with :('}
9494
} else if (!rootSomeItemIsFile) {

src/tutorials/0004-mutable-file-system/08.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const validate = async (result, ipfs) => {
1616
}
1717

1818
// identify files that should have been moved
19-
let uploadedFiles = window.uploadedFiles || false
19+
let uploadedFiles = window.uploadedFiles || []
2020
let uploadedFilenames = uploadedFiles.map(file => file.name.toString()).sort()
2121

2222
// check whether user returned the contents of /some/stuff
@@ -38,7 +38,7 @@ const validate = async (result, ipfs) => {
3838

3939
if (!result) {
4040
return { fail: 'You forgot to return a result. Did you accidentally edit the return statement?' }
41-
} else if (uploadedFiles === false) {
41+
} else if (uploadedFiles.length === 0) {
4242
// Shouldn't happen because you can't hit submit without uploading files
4343
return { fail: 'Oops! You forgot to upload files to work with :(' }
4444
} else if (result instanceof Error && result.message === 'Unexpected token const') {

0 commit comments

Comments
 (0)