feat: mobile curriculum testing (#47586)
* feat: first draft of action and cypress spec * feat: test all generated challenges * fix: better identification of block * action: update cypress config * action: upload to dashboard * action: testing js cert challenges * fix: unnecessary after user code for Make a Person * feat: capture console log output for assert test * fix: remove after seed code * fix: change const to let * fix: test * action: disable js certification * action: stop checking out branch in action * action: check out right mobile repo Co-authored-by: sembauke <semboot699@gmail.com>pull/48052/head
parent
035b475500
commit
441f11db38
|
@ -0,0 +1,72 @@
|
|||
name: Mobile Curriculum Tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
branches-ignore:
|
||||
- 'renovate/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
jobs:
|
||||
mobile-test:
|
||||
name: Test curriculum for mobile app
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Checkout Source Files
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
|
||||
- name: Checkout mobile
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
with:
|
||||
repository: freeCodeCamp/mobile
|
||||
path: mobile
|
||||
|
||||
- name: Use Node.js 16.x
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: 'npm'
|
||||
|
||||
- name: Setup Flutter 3.0.x
|
||||
uses: subosito/flutter-action@9d48f4efd5460d7013af812069d08b23f37aed20 # tag=v2
|
||||
with:
|
||||
flutter-version: '3.0.x'
|
||||
channel: 'stable'
|
||||
cache: true
|
||||
cache-key: flutter-3.0.x
|
||||
cache-path: ${{ runner.tool_cache }}/flutter
|
||||
|
||||
- name: Set freeCodeCamp Environment Variables
|
||||
run: cp sample.env .env
|
||||
|
||||
- name: Install and Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run create:config
|
||||
npm run build:curriculum
|
||||
|
||||
- name: Generate mobile test files
|
||||
run: |
|
||||
cd mobile/mobile-app
|
||||
echo "DEVELOPMENTMODE=true" > .env
|
||||
echo "NEWSURL=https://www.freecodecamp.org/news/ghost/api/v3/content/" >> .env
|
||||
flutter pub get
|
||||
flutter test test/widget_test.dart
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v2
|
||||
with:
|
||||
record: ${{ env.CYPRESS_RECORD_KEY != 0 }}
|
||||
start: npx serve
|
||||
wait-on: http://localhost:3000
|
||||
wait-on-timeout: 1200
|
||||
config: retries=1,screenshotOnRunFailure=false,video=false,baseUrl=http://localhost:3000/mobile/mobile-app/generated-tests/
|
||||
browser: chrome
|
||||
headless: true
|
||||
spec: cypress/integration/mobile-learn/test-challenges.js
|
||||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -37,12 +37,6 @@ assert(code.match(/quotient/g).length === 1);
|
|||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
(function(y){return 'quotient = '+y;})(quotient);
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
|
|
|
@ -78,14 +78,6 @@ assert(myStr === 'FirstLine\n\t\\SecondLine\nThirdLine');
|
|||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
(function(){
|
||||
if (myStr !== undefined){
|
||||
console.log('myStr:\n' + myStr);}})();
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
|
|
|
@ -31,12 +31,6 @@ assert(/var\s+a\s*=\s*9(\s*;?\s*)$/.test(code));
|
|||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
if(typeof a !== 'undefined') {(function(a){return "a = " + a;})(a);} else { (function() {return 'a is undefined';})(); }
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
|
|
|
@ -62,12 +62,6 @@ assert(code.match(/"/g).length === 4 && code.match(/'/g).length === 2);
|
|||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
(function() { return "myStr = " + myStr; })();
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
|
|
|
@ -98,7 +98,7 @@ function nextInLine(arr, item) {
|
|||
}
|
||||
|
||||
// Setup
|
||||
const testArr = [1, 2, 3, 4, 5];
|
||||
let testArr = [1, 2, 3, 4, 5];
|
||||
|
||||
// Display code
|
||||
console.log("Before: " + JSON.stringify(testArr));
|
||||
|
@ -109,7 +109,7 @@ console.log("After: " + JSON.stringify(testArr));
|
|||
# --solutions--
|
||||
|
||||
```js
|
||||
const testArr = [1, 2, 3, 4, 5];
|
||||
let testArr = [1, 2, 3, 4, 5];
|
||||
|
||||
function nextInLine(arr, item) {
|
||||
arr.push(item);
|
||||
|
|
|
@ -53,7 +53,8 @@ assert(
|
|||
`bicycle.setGear(48)` should change the `gear` value to 48.
|
||||
|
||||
```js
|
||||
assert(new bicycle.setGear(48).gear === 48);
|
||||
bicycle.setGear(48);
|
||||
assert(bicycle.gear === 48);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
|
|
@ -137,14 +137,6 @@ assert.strictEqual(
|
|||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
if(bob){
|
||||
bob = new Person("Bob Ross");
|
||||
}
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
|
|
|
@ -79,23 +79,55 @@ assert(beagle.constructor === Dog);
|
|||
`beagle.eat()` should log the string `nom nom nom`
|
||||
|
||||
```js
|
||||
console.log = function (msg) {
|
||||
throw msg;
|
||||
};
|
||||
assert.throws(() => beagle.eat(), 'nom nom nom');
|
||||
capture();
|
||||
beagle.eat();
|
||||
uncapture();
|
||||
assert(logOutput == 'nom nom nom');
|
||||
```
|
||||
|
||||
`beagle.bark()` should log the string `Woof!`
|
||||
|
||||
```js
|
||||
console.log = function (msg) {
|
||||
throw msg;
|
||||
};
|
||||
assert.throws(() => beagle.bark(), 'Woof!');
|
||||
capture();
|
||||
beagle.bark();
|
||||
uncapture();
|
||||
assert(logOutput == 'Woof!');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --before-user-code--
|
||||
|
||||
```js
|
||||
var logOutput = "";
|
||||
var originalConsole = console
|
||||
function capture() {
|
||||
var nativeLog = console.log;
|
||||
console.log = function (message) {
|
||||
logOutput = message;
|
||||
if(nativeLog.apply) {
|
||||
nativeLog.apply(originalConsole, arguments);
|
||||
} else {
|
||||
var nativeMsg = Array.prototype.slice.apply(arguments).join(' ');
|
||||
nativeLog(nativeMsg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function uncapture() {
|
||||
console.log = originalConsole.log;
|
||||
}
|
||||
|
||||
capture();
|
||||
```
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
uncapture();
|
||||
(function() { return logOutput || "console.log never called"; })();
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import currData from '../../../config/curriculum.json';
|
||||
import { orderedSuperBlockInfo } from '../../../tools/scripts/build/build-external-curricula-data';
|
||||
|
||||
const publicSB = orderedSuperBlockInfo
|
||||
.filter(sb => sb.public === true)
|
||||
.map(sb => sb.dashedName);
|
||||
|
||||
describe('Test challenges in mobile', () => {
|
||||
for (let superBlock of publicSB) {
|
||||
for (let currBlock of Object.values(currData[superBlock]['blocks'])) {
|
||||
describe(`SuperBlock: ${superBlock} - Block: ${currBlock['meta']['name']}`, () => {
|
||||
for (let currChallenge of currBlock['challenges']) {
|
||||
it(`Challenge: ${currChallenge['title']}(${currChallenge['id']})`, () => {
|
||||
cy.visit(
|
||||
`/${superBlock}/${currChallenge['block']}/${currChallenge['id']}`,
|
||||
{
|
||||
onBeforeLoad(win) {
|
||||
cy.spy(win.console, 'log').as('consoleLog');
|
||||
}
|
||||
}
|
||||
);
|
||||
cy.get('@consoleLog').should('be.calledWith', 'completed');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue