mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-12-18 03:27:02 -05:00
Merge pull request #6314 from LLK/release/2021-11-17
[Master] release/2021-11-17
This commit is contained in:
commit
27bdbf0286
19 changed files with 709 additions and 1141 deletions
1
.babelrc
1
.babelrc
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"plugins": [
|
"plugins": [
|
||||||
|
"transform-async-to-generator",
|
||||||
"transform-object-rest-spread",
|
"transform-object-rest-spread",
|
||||||
"transform-require-context",
|
"transform-require-context",
|
||||||
"syntax-dynamic-import"
|
"syntax-dynamic-import"
|
||||||
|
|
|
@ -100,21 +100,7 @@ aliases:
|
||||||
- run:
|
- run:
|
||||||
name: "integration tests with Jest"
|
name: "integration tests with Jest"
|
||||||
command: |
|
command: |
|
||||||
JEST_JUNIT_OUTPUT_NAME=integration-jest-results.xml npm run test:integration:jest:remote -- --reporters=jest-junit
|
JEST_JUNIT_OUTPUT_NAME=integration-jest-results.xml npm run test:integration:remote -- --reporters=jest-junit
|
||||||
- store_test_results:
|
|
||||||
path: test/results
|
|
||||||
- &integration_tap
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- *restore_git_cache
|
|
||||||
- checkout
|
|
||||||
- *restore_npm_cache
|
|
||||||
- run:
|
|
||||||
name: "integration tests with Tap"
|
|
||||||
command: |
|
|
||||||
mkdir ./test/results
|
|
||||||
npm run test:smoke:sauce -- --output-file ./test/results/integration-raw-tap.tap
|
|
||||||
npm run test:smoke:convertReportToXunit
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: test/results
|
path: test/results
|
||||||
- &update-translations
|
- &update-translations
|
||||||
|
@ -139,12 +125,8 @@ jobs:
|
||||||
<<: *deploy
|
<<: *deploy
|
||||||
integration-staging-jest:
|
integration-staging-jest:
|
||||||
<<: *integration_jest
|
<<: *integration_jest
|
||||||
integration-staging-tap:
|
|
||||||
<<: *integration_tap
|
|
||||||
integration-production-jest:
|
integration-production-jest:
|
||||||
<<: *integration_jest
|
<<: *integration_jest
|
||||||
integration-production-tap:
|
|
||||||
<<: *integration_tap
|
|
||||||
update-translations:
|
update-translations:
|
||||||
<<: *update-translations
|
<<: *update-translations
|
||||||
|
|
||||||
|
@ -201,18 +183,6 @@ workflows:
|
||||||
- develop
|
- develop
|
||||||
- /^hotfix\/.*/
|
- /^hotfix\/.*/
|
||||||
- /^release\/.*/
|
- /^release\/.*/
|
||||||
- integration-staging-tap:
|
|
||||||
context:
|
|
||||||
- scratch-www-all
|
|
||||||
- scratch-www-staging
|
|
||||||
requires:
|
|
||||||
- deploy-staging
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- develop
|
|
||||||
- /^hotfix\/.*/
|
|
||||||
- /^release\/.*/
|
|
||||||
- integration-production-jest:
|
- integration-production-jest:
|
||||||
context:
|
context:
|
||||||
- scratch-www-all
|
- scratch-www-all
|
||||||
|
@ -223,16 +193,6 @@ workflows:
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- integration-production-tap:
|
|
||||||
context:
|
|
||||||
- scratch-www-all
|
|
||||||
- scratch-www-production
|
|
||||||
requires:
|
|
||||||
- deploy-production
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
Update-translations:
|
Update-translations:
|
||||||
triggers:
|
triggers:
|
||||||
- schedule: # every evening at 7pm EST (8pm EDT, Midnight UTC)
|
- schedule: # every evening at 7pm EST (8pm EDT, Midnight UTC)
|
||||||
|
|
240
package-lock.json
generated
240
package-lock.json
generated
|
@ -308,9 +308,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.16.2",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.3.tgz",
|
||||||
"integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==",
|
"integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
|
@ -325,9 +325,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/traverse": {
|
"@babel/traverse": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz",
|
||||||
"integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==",
|
"integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.16.0",
|
"@babel/code-frame": "^7.16.0",
|
||||||
|
@ -335,7 +335,7 @@
|
||||||
"@babel/helper-function-name": "^7.16.0",
|
"@babel/helper-function-name": "^7.16.0",
|
||||||
"@babel/helper-hoist-variables": "^7.16.0",
|
"@babel/helper-hoist-variables": "^7.16.0",
|
||||||
"@babel/helper-split-export-declaration": "^7.16.0",
|
"@babel/helper-split-export-declaration": "^7.16.0",
|
||||||
"@babel/parser": "^7.16.0",
|
"@babel/parser": "^7.16.3",
|
||||||
"@babel/types": "^7.16.0",
|
"@babel/types": "^7.16.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
|
@ -479,40 +479,40 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-compilation-targets": {
|
"@babel/helper-compilation-targets": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz",
|
||||||
"integrity": "sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==",
|
"integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/compat-data": "^7.16.0",
|
"@babel/compat-data": "^7.16.0",
|
||||||
"@babel/helper-validator-option": "^7.14.5",
|
"@babel/helper-validator-option": "^7.14.5",
|
||||||
"browserslist": "^4.16.6",
|
"browserslist": "^4.17.5",
|
||||||
"semver": "^6.3.0"
|
"semver": "^6.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"version": "4.17.6",
|
"version": "4.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz",
|
||||||
"integrity": "sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==",
|
"integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"caniuse-lite": "^1.0.30001274",
|
"caniuse-lite": "^1.0.30001280",
|
||||||
"electron-to-chromium": "^1.3.886",
|
"electron-to-chromium": "^1.3.896",
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.1",
|
||||||
"node-releases": "^2.0.1",
|
"node-releases": "^2.0.1",
|
||||||
"picocolors": "^1.0.0"
|
"picocolors": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001274",
|
"version": "1.0.30001280",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001274.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001280.tgz",
|
||||||
"integrity": "sha512-+Nkvv0fHyhISkiMIjnyjmf5YJcQ1IQHZN6U9TLUMroWR38FNwpsC51Gb68yueafX1V6ifOisInSgP9WJFS13ew==",
|
"integrity": "sha512-kFXwYvHe5rix25uwueBxC569o53J6TpnGu0BEEn+6Lhl2vsnAumRFWEBhDft1fwyo6m1r4i+RqA4+163FpeFcA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"electron-to-chromium": {
|
"electron-to-chromium": {
|
||||||
"version": "1.3.887",
|
"version": "1.3.898",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.887.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.898.tgz",
|
||||||
"integrity": "sha512-QQUumrEjFDKSVYVdaeBmFdyQGoaV+fCSMyWHvfx/u22bRHSTeBQYt6P4jMY+gFd4kgKB9nqk7RMtWkDB49OYPA==",
|
"integrity": "sha512-dxEsaHy9Ter268LO7P8uWomuChbyML4zZk5F9+UZSozFRS7ggC5cQ8fPIM8Pec+6uWGdujuDagQhIbqjohUK2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"picocolors": {
|
"picocolors": {
|
||||||
|
@ -707,9 +707,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.16.2",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.3.tgz",
|
||||||
"integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==",
|
"integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
|
@ -724,9 +724,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/traverse": {
|
"@babel/traverse": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz",
|
||||||
"integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==",
|
"integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.16.0",
|
"@babel/code-frame": "^7.16.0",
|
||||||
|
@ -734,7 +734,7 @@
|
||||||
"@babel/helper-function-name": "^7.16.0",
|
"@babel/helper-function-name": "^7.16.0",
|
||||||
"@babel/helper-hoist-variables": "^7.16.0",
|
"@babel/helper-hoist-variables": "^7.16.0",
|
||||||
"@babel/helper-split-export-declaration": "^7.16.0",
|
"@babel/helper-split-export-declaration": "^7.16.0",
|
||||||
"@babel/parser": "^7.16.0",
|
"@babel/parser": "^7.16.3",
|
||||||
"@babel/types": "^7.16.0",
|
"@babel/types": "^7.16.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
|
@ -926,9 +926,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.16.2",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.3.tgz",
|
||||||
"integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==",
|
"integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
|
@ -943,9 +943,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/traverse": {
|
"@babel/traverse": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz",
|
||||||
"integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==",
|
"integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.16.0",
|
"@babel/code-frame": "^7.16.0",
|
||||||
|
@ -953,7 +953,7 @@
|
||||||
"@babel/helper-function-name": "^7.16.0",
|
"@babel/helper-function-name": "^7.16.0",
|
||||||
"@babel/helper-hoist-variables": "^7.16.0",
|
"@babel/helper-hoist-variables": "^7.16.0",
|
||||||
"@babel/helper-split-export-declaration": "^7.16.0",
|
"@babel/helper-split-export-declaration": "^7.16.0",
|
||||||
"@babel/parser": "^7.16.0",
|
"@babel/parser": "^7.16.3",
|
||||||
"@babel/types": "^7.16.0",
|
"@babel/types": "^7.16.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
|
@ -1088,13 +1088,13 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/helpers": {
|
"@babel/helpers": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.3.tgz",
|
||||||
"integrity": "sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==",
|
"integrity": "sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/template": "^7.16.0",
|
"@babel/template": "^7.16.0",
|
||||||
"@babel/traverse": "^7.16.0",
|
"@babel/traverse": "^7.16.3",
|
||||||
"@babel/types": "^7.16.0"
|
"@babel/types": "^7.16.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1159,9 +1159,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.16.2",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.3.tgz",
|
||||||
"integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==",
|
"integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
|
@ -1176,9 +1176,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/traverse": {
|
"@babel/traverse": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz",
|
||||||
"integrity": "sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==",
|
"integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.16.0",
|
"@babel/code-frame": "^7.16.0",
|
||||||
|
@ -1186,7 +1186,7 @@
|
||||||
"@babel/helper-function-name": "^7.16.0",
|
"@babel/helper-function-name": "^7.16.0",
|
||||||
"@babel/helper-hoist-variables": "^7.16.0",
|
"@babel/helper-hoist-variables": "^7.16.0",
|
||||||
"@babel/helper-split-export-declaration": "^7.16.0",
|
"@babel/helper-split-export-declaration": "^7.16.0",
|
||||||
"@babel/parser": "^7.16.0",
|
"@babel/parser": "^7.16.3",
|
||||||
"@babel/types": "^7.16.0",
|
"@babel/types": "^7.16.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
|
@ -1483,24 +1483,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@formatjs/intl-pluralrules": {
|
"@formatjs/intl-pluralrules": {
|
||||||
"version": "4.0.28",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-pluralrules/-/intl-pluralrules-4.0.28.tgz",
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-pluralrules/-/intl-pluralrules-4.1.0.tgz",
|
||||||
"integrity": "sha512-sWtOHwEff6/cHuSk5l6zpcB3POPCYlBx3DUGASb7QU6AD/tO/oKW6oRHOCHbBdspkBEsUJByZ9LlP2r0Xw6yPQ==",
|
"integrity": "sha512-rJFWETXa1OOcru4kqjEz/MUyBxdcMWhbmqKVjDBVZ6HF4ZqkC1TUWQkj+jqIxDiShQ6/J7QLMOGMwiGDjGepHg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@formatjs/ecma402-abstract": "1.9.4",
|
"@formatjs/ecma402-abstract": "1.9.5",
|
||||||
|
"@formatjs/intl-localematcher": "0.2.18",
|
||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formatjs/ecma402-abstract": {
|
|
||||||
"version": "1.9.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.9.4.tgz",
|
|
||||||
"integrity": "sha512-ePJXI7tWC9PBxQxS7jtbkCLGVmpC8MH8n9Yjmg8dsh9wXK9svu7nAbq76Oiu5Zb+5GVkLkeTVerlSvHCbNImlA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"tslib": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||||
|
@ -2901,6 +2893,19 @@
|
||||||
"lodash": "^4.17.4"
|
"lodash": "^4.17.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-helper-remap-async-to-generator": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-function-name": "^6.24.1",
|
||||||
|
"babel-runtime": "^6.22.0",
|
||||||
|
"babel-template": "^6.24.1",
|
||||||
|
"babel-traverse": "^6.24.1",
|
||||||
|
"babel-types": "^6.24.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-helper-replace-supers": {
|
"babel-helper-replace-supers": {
|
||||||
"version": "6.24.1",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
||||||
|
@ -3039,6 +3044,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-plugin-syntax-async-functions": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"babel-plugin-syntax-dynamic-import": {
|
"babel-plugin-syntax-dynamic-import": {
|
||||||
"version": "6.18.0",
|
"version": "6.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
|
||||||
|
@ -3063,6 +3074,17 @@
|
||||||
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"babel-plugin-transform-async-to-generator": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-remap-async-to-generator": "^6.24.1",
|
||||||
|
"babel-plugin-syntax-async-functions": "^6.8.0",
|
||||||
|
"babel-runtime": "^6.22.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-transform-es2015-arrow-functions": {
|
"babel-plugin-transform-es2015-arrow-functions": {
|
||||||
"version": "6.22.0",
|
"version": "6.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||||
|
@ -3558,6 +3580,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
|
||||||
"integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==",
|
"integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
||||||
|
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -4481,9 +4509,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001275",
|
"version": "1.0.30001282",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001275.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz",
|
||||||
"integrity": "sha512-ihJVvj8RX0kn9GgP43HKhb5q9s2XQn4nEQhdldEJvZhCsuiB2XOq6fAMYQZaN6FPWfsr2qU0cdL0CSbETwbJAg==",
|
"integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"canvas-fit": {
|
"canvas-fit": {
|
||||||
|
@ -4627,9 +4655,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chromedriver": {
|
"chromedriver": {
|
||||||
"version": "94.0.0",
|
"version": "95.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-94.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-95.0.0.tgz",
|
||||||
"integrity": "sha512-x4hK7R7iOyAhdLHJEcOyGBW/oa2kno6AqpHVLd+n3G7c2Vk9XcAXMz84XhNItqykJvTc6E3z/JRIT1eHYH//Eg==",
|
"integrity": "sha512-HwSg7S0ZZYsHTjULwxFHrrUqEpz1+ljDudJM3eOquvqD5QKnR5pSe/GlBTY9UU2tVFRYz8bEHYC4Y8qxciQiLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@testim/chrome-version": "^1.0.7",
|
"@testim/chrome-version": "^1.0.7",
|
||||||
|
@ -6263,9 +6291,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ignore": {
|
"ignore": {
|
||||||
"version": "5.1.8",
|
"version": "5.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
|
||||||
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
|
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-extglob": {
|
"is-extglob": {
|
||||||
|
@ -8492,9 +8520,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.14.4",
|
"version": "1.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
|
||||||
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
|
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"font-atlas": {
|
"font-atlas": {
|
||||||
|
@ -19164,9 +19192,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.11.1",
|
"version": "0.13.9",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
|
@ -20524,21 +20552,35 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scratch-blocks": {
|
"scratch-blocks": {
|
||||||
"version": "0.1.0-prerelease.20211103084955",
|
"version": "0.1.0-prerelease.20211110095305",
|
||||||
"resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.20211103084955.tgz",
|
"resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.20211110095305.tgz",
|
||||||
"integrity": "sha512-CELZCOHCLAZktFBNuzE4gn/c+uXTlM/AakQOQAZG3VQNpRolzsKdCFdKjmFGGLTrSV9aUO1GsBRtwcWsgdJXIA==",
|
"integrity": "sha512-EJC1kRxMl/e80QWOI4GqJBuYwJ2jX0v/QhiHRY97m5uys5mozBWgoxT/f4qPRK1KYUP36ACWMpjkhftvqxRYwA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"exports-loader": "0.6.3",
|
"exports-loader": "0.6.3",
|
||||||
"google-closure-library": "20190301.0.0",
|
"google-closure-library": "20190301.0.0",
|
||||||
"imports-loader": "0.6.5",
|
"imports-loader": "0.6.5",
|
||||||
"scratch-l10n": "3.14.20211103031555"
|
"scratch-l10n": "3.14.20211110031601"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"scratch-l10n": {
|
||||||
|
"version": "3.14.20211110031601",
|
||||||
|
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.14.20211110031601.tgz",
|
||||||
|
"integrity": "sha512-XJQv2MSiu3bMkFPBSp7U0+T/omMiHnL60KGEA3OLdfX0hUgwwWoOduvx3O7rIpLp53zmOLds3eAa3hd/wh1E+g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/cli": "^7.1.2",
|
||||||
|
"@babel/core": "^7.1.2",
|
||||||
|
"babel-plugin-react-intl": "^3.0.1",
|
||||||
|
"transifex": "1.6.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scratch-gui": {
|
"scratch-gui": {
|
||||||
"version": "0.1.0-prerelease.20211103150403",
|
"version": "0.1.0-prerelease.20211117061326",
|
||||||
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20211103150403.tgz",
|
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20211117061326.tgz",
|
||||||
"integrity": "sha512-SA7pb/Bhz6CwJvAbWegtnrxfuc+rvEO3WBYQkV7Q/SxmXKO4GYdqSc4mMHo6oDm08RMcDdLrD/CEIL/KZi67PA==",
|
"integrity": "sha512-+JF0VztQWTtbVFnsRWpINXCU0HpbmV79or80Ho3akOvYkrJtGdMZt1lyEqYUflBAGRrLthZsefl/wiTLay6wfw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"arraybuffer-loader": "^1.0.6",
|
"arraybuffer-loader": "^1.0.6",
|
||||||
|
@ -20589,14 +20631,14 @@
|
||||||
"redux": "3.7.2",
|
"redux": "3.7.2",
|
||||||
"redux-throttle": "0.1.1",
|
"redux-throttle": "0.1.1",
|
||||||
"scratch-audio": "0.1.0-prerelease.20200528195344",
|
"scratch-audio": "0.1.0-prerelease.20200528195344",
|
||||||
"scratch-blocks": "0.1.0-prerelease.20211103084955",
|
"scratch-blocks": "0.1.0-prerelease.20211110095305",
|
||||||
"scratch-l10n": "3.14.20211103031555",
|
"scratch-l10n": "3.14.20211117031600",
|
||||||
"scratch-paint": "0.2.0-prerelease.20211027080909",
|
"scratch-paint": "0.2.0-prerelease.20211027080909",
|
||||||
"scratch-render": "0.1.0-prerelease.20211028200436",
|
"scratch-render": "0.1.0-prerelease.20211028200436",
|
||||||
"scratch-render-fonts": "1.0.0-prerelease.20210401210003",
|
"scratch-render-fonts": "1.0.0-prerelease.20210401210003",
|
||||||
"scratch-storage": "1.3.5",
|
"scratch-storage": "1.3.5",
|
||||||
"scratch-svg-renderer": "0.2.0-prerelease.20210727023023",
|
"scratch-svg-renderer": "0.2.0-prerelease.20210727023023",
|
||||||
"scratch-vm": "0.2.0-prerelease.20211103090905",
|
"scratch-vm": "0.2.0-prerelease.20211110140254",
|
||||||
"startaudiocontext": "1.2.1",
|
"startaudiocontext": "1.2.1",
|
||||||
"style-loader": "^0.23.0",
|
"style-loader": "^0.23.0",
|
||||||
"text-encoding": "0.7.0",
|
"text-encoding": "0.7.0",
|
||||||
|
@ -20636,13 +20678,13 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"version": "4.17.6",
|
"version": "4.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz",
|
||||||
"integrity": "sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==",
|
"integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"caniuse-lite": "^1.0.30001274",
|
"caniuse-lite": "^1.0.30001280",
|
||||||
"electron-to-chromium": "^1.3.886",
|
"electron-to-chromium": "^1.3.896",
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.1",
|
||||||
"node-releases": "^2.0.1",
|
"node-releases": "^2.0.1",
|
||||||
"picocolors": "^1.0.0"
|
"picocolors": "^1.0.0"
|
||||||
|
@ -20747,9 +20789,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"electron-to-chromium": {
|
"electron-to-chromium": {
|
||||||
"version": "1.3.887",
|
"version": "1.3.900",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.887.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.900.tgz",
|
||||||
"integrity": "sha512-QQUumrEjFDKSVYVdaeBmFdyQGoaV+fCSMyWHvfx/u22bRHSTeBQYt6P4jMY+gFd4kgKB9nqk7RMtWkDB49OYPA==",
|
"integrity": "sha512-SuXbQD8D4EjsaBaJJxySHbC+zq8JrFfxtb4GIr4E9n1BcROyMcRrJCYQNpJ9N+Wjf5mFp7Wp0OHykd14JNEzzQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"has-flag": {
|
"has-flag": {
|
||||||
|
@ -21012,9 +21054,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scratch-l10n": {
|
"scratch-l10n": {
|
||||||
"version": "3.14.20211103031555",
|
"version": "3.14.20211117031600",
|
||||||
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.14.20211103031555.tgz",
|
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.14.20211117031600.tgz",
|
||||||
"integrity": "sha512-eJrTp6JJyTWeyXiWuLUPtGfy7tG4sGHeCz6gNYtH2TMLwzQfu2r2RRbt29HS7zkkxdnqWZjVkOxVnosWb/1EuQ==",
|
"integrity": "sha512-ekVIL9BLg6ZISYYbd3ID35rg0NcCyYvrrmgtIwUl0y7bgc+DSFBaZZoQN0rBahIM6tsEDpbc278nMDHKMhs0VA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/cli": "^7.1.2",
|
"@babel/cli": "^7.1.2",
|
||||||
|
@ -21243,9 +21285,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"scratch-vm": {
|
"scratch-vm": {
|
||||||
"version": "0.2.0-prerelease.20211103090905",
|
"version": "0.2.0-prerelease.20211110140254",
|
||||||
"resolved": "https://registry.npmjs.org/scratch-vm/-/scratch-vm-0.2.0-prerelease.20211103090905.tgz",
|
"resolved": "https://registry.npmjs.org/scratch-vm/-/scratch-vm-0.2.0-prerelease.20211110140254.tgz",
|
||||||
"integrity": "sha512-nfqvuNCOLzippBHcbfVQoWXVOLTdrlIXfFnhYTzVthLsl32ApUsNU9P3iA50HsAkwqvZmcHM4SQFLXZEJgonkQ==",
|
"integrity": "sha512-6gNNDXJg3WagT/tA7bjLJcQeDqhvu/FZVdIAlS3A96C/6sT3jiWljDeRpzl/EbJWAxwzbQ6CBiZ3ZDf9eLgQ2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vernier/godirect": "1.5.0",
|
"@vernier/godirect": "1.5.0",
|
||||||
|
|
20
package.json
20
package.json
|
@ -7,14 +7,8 @@
|
||||||
"test": "npm run test:lint && npm run build && npm run test:unit",
|
"test": "npm run test:lint && npm run build && npm run test:unit",
|
||||||
"test:lint": "eslint . --ext .js,.jsx,.json",
|
"test:lint": "eslint . --ext .js,.jsx,.json",
|
||||||
"test:lint:ci": "eslint . --ext .js,.jsx,.json --format junit -o ./test/results/lint-results.xml",
|
"test:lint:ci": "eslint . --ext .js,.jsx,.json --format junit -o ./test/results/lint-results.xml",
|
||||||
"test:integration": "npm run test:integration:jest && npm run test:smoke",
|
"test:integration": "jest ./test/integration/*.test.js --reporters=default --runInBand",
|
||||||
"test:integration:jest": "jest ./test/integration/*.test.js --reporters=default --runInBand",
|
"test:integration:remote": "SMOKE_REMOTE=true jest ./test/integration/*.test.js --reporters=default --runInBand",
|
||||||
"test:integration:remote": "npm run test:integration:jest:remote && npm run test:smoke:sauce",
|
|
||||||
"test:integration:jest:remote": "SMOKE_REMOTE=true jest ./test/integration/*.test.js --reporters=default --runInBand",
|
|
||||||
"test:smoke": "tap ./test/integration-legacy/smoke-testing/*.js --timeout=3600 --no-coverage -R classic",
|
|
||||||
"test:smoke:verbose": "tap ./test/integration-legacy/smoke-testing/*.js --timeout=3600 --no-coverage -R spec",
|
|
||||||
"test:smoke:sauce": "SMOKE_REMOTE=true tap ./test/integration-legacy/smoke-testing/*.js --timeout=60000 --no-coverage -R classic",
|
|
||||||
"test:smoke:convertReportToXunit": "tap ./test/results/integration-raw-tap.tap --no-coverage -R xunit > ./test/results/integration-tap-results.xml",
|
|
||||||
"test:unit": "npm run test:unit:jest && npm run test:unit:tap",
|
"test:unit": "npm run test:unit:jest && npm run test:unit:tap",
|
||||||
"test:unit:jest": "npm run test:unit:jest:unit && npm run test:unit:jest:localization",
|
"test:unit:jest": "npm run test:unit:jest:unit && npm run test:unit:jest:localization",
|
||||||
"test:unit:jest:unit": "jest ./test/unit/ --reporters=default",
|
"test:unit:jest:unit": "jest ./test/unit/ --reporters=default",
|
||||||
|
@ -63,7 +57,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@formatjs/intl-locale": "2.4.34",
|
"@formatjs/intl-locale": "2.4.34",
|
||||||
"@formatjs/intl-pluralrules": "4.0.28",
|
"@formatjs/intl-pluralrules": "4.1.0",
|
||||||
"@formatjs/intl-relativetimeformat": "8.1.8",
|
"@formatjs/intl-relativetimeformat": "8.1.8",
|
||||||
"async": "3.1.0",
|
"async": "3.1.0",
|
||||||
"autoprefixer": "6.3.6",
|
"autoprefixer": "6.3.6",
|
||||||
|
@ -72,12 +66,13 @@
|
||||||
"babel-eslint": "10.0.3",
|
"babel-eslint": "10.0.3",
|
||||||
"babel-loader": "7.1.0",
|
"babel-loader": "7.1.0",
|
||||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||||
|
"babel-plugin-transform-async-to-generator": "6.24.1",
|
||||||
"babel-plugin-transform-object-rest-spread": "6.26.0",
|
"babel-plugin-transform-object-rest-spread": "6.26.0",
|
||||||
"babel-plugin-transform-require-context": "0.1.1",
|
"babel-plugin-transform-require-context": "0.1.1",
|
||||||
"babel-preset-es2015": "6.22.0",
|
"babel-preset-es2015": "6.22.0",
|
||||||
"babel-preset-react": "6.22.0",
|
"babel-preset-react": "6.22.0",
|
||||||
"bowser": "1.9.4",
|
"bowser": "1.9.4",
|
||||||
"chromedriver": "94.0.0",
|
"chromedriver": "95.0.0",
|
||||||
"classnames": "2.2.5",
|
"classnames": "2.2.5",
|
||||||
"cookie": "0.4.1",
|
"cookie": "0.4.1",
|
||||||
"copy-webpack-plugin": "4.6.0",
|
"copy-webpack-plugin": "4.6.0",
|
||||||
|
@ -130,9 +125,10 @@
|
||||||
"redux": "3.5.2",
|
"redux": "3.5.2",
|
||||||
"redux-mock-store": "1.5.4",
|
"redux-mock-store": "1.5.4",
|
||||||
"redux-thunk": "2.0.1",
|
"redux-thunk": "2.0.1",
|
||||||
|
"regenerator-runtime": "0.13.9",
|
||||||
"sass-loader": "6.0.6",
|
"sass-loader": "6.0.6",
|
||||||
"scratch-gui": "0.1.0-prerelease.20211103150403",
|
"scratch-gui": "0.1.0-prerelease.20211117061326",
|
||||||
"scratch-l10n": "3.14.20211103031555",
|
"scratch-l10n": "3.14.20211117031600",
|
||||||
"selenium-webdriver": "3.6.0",
|
"selenium-webdriver": "3.6.0",
|
||||||
"slick-carousel": "1.6.0",
|
"slick-carousel": "1.6.0",
|
||||||
"style-loader": "0.12.3",
|
"style-loader": "0.12.3",
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
|
import 'regenerator-runtime/runtime'; // Needed for async/await
|
||||||
const jar = require('./lib/jar');
|
const jar = require('./lib/jar');
|
||||||
|
import intlPolyfill from './lib/intl-polyfill';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
* L10N
|
* L10N
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
(() => {
|
(async () => {
|
||||||
/*
|
/*
|
||||||
* Bind locale code from cookie if available. Uses navigator language API as a fallback.
|
* Bind locale code from cookie if available. Uses navigator language API as a fallback.
|
||||||
*
|
*
|
||||||
|
@ -35,6 +37,7 @@ const jar = require('./lib/jar');
|
||||||
|
|
||||||
window._locale = updateLocale();
|
window._locale = updateLocale();
|
||||||
document.documentElement.lang = window._locale;
|
document.documentElement.lang = window._locale;
|
||||||
|
await intlPolyfill(window._locale);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// IMPORTANT: any changes to the time algorithm also need to be made in the corresponding
|
// IMPORTANT: any changes to the time algorithm also need to be made in the corresponding
|
||||||
// scratchr2 file 'lib/format-time.js'
|
// scratchr2 file 'lib/format-time.js'
|
||||||
|
|
||||||
require('./relative-time-polyfill');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Given a timestamp in the future, calculate the largest, closest unit to show.
|
Given a timestamp in the future, calculate the largest, closest unit to show.
|
||||||
On the high end we stop at hours. e.g. 15 days is still counted in hours not days or weeks.
|
On the high end we stop at hours. e.g. 15 days is still counted in hours not days or weeks.
|
||||||
|
|
313
src/lib/intl-polyfill.js
Normal file
313
src/lib/intl-polyfill.js
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
// this file should only be `required` in the format-time
|
||||||
|
// when Intl.RelativeTimeFormat is not available (Safari < 14), but
|
||||||
|
// we're not currently able to do the code splitting in www, and it
|
||||||
|
// is always included. To reduce the amount of data that's loaded limit
|
||||||
|
// the number of languages loaded to just the top few that are still using
|
||||||
|
// safari <14. These seven account for most uses.
|
||||||
|
// relativetimeformat depends on locale which also needs to be polyfilled in
|
||||||
|
// safari <14
|
||||||
|
// The plural rules is required for safari 12.
|
||||||
|
import 'regenerator-runtime/runtime'; // Needed for async/await
|
||||||
|
import {shouldPolyfill as shouldPolyfillLocale} from '@formatjs/intl-locale/should-polyfill';
|
||||||
|
import {shouldPolyfill as shouldPolyfillRelativeTimeFormat} from '@formatjs/intl-relativetimeformat/should-polyfill';
|
||||||
|
import {shouldPolyfill as shouldPolyfillPluralRules} from '@formatjs/intl-pluralrules/should-polyfill';
|
||||||
|
/**
|
||||||
|
* polyfill all the parts needed from intl
|
||||||
|
* @param {string} locale currently selected locale
|
||||||
|
* @return {Promise} returns a promise that resolves when everything is loaded
|
||||||
|
*/
|
||||||
|
const intlPolyfill = async function (locale) {
|
||||||
|
if (!(shouldPolyfillLocale() ||
|
||||||
|
shouldPolyfillPluralRules(locale) ||
|
||||||
|
shouldPolyfillRelativeTimeFormat(locale))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldPolyfillRelativeTimeFormat(locale)) {
|
||||||
|
await import('@formatjs/intl-relativetimeformat/polyfill');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldPolyfillPluralRules(locale)) {
|
||||||
|
await import('@formatjs/intl-pluralrules/polyfill');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldPolyfillLocale(locale)) {
|
||||||
|
await import('@formatjs/intl-locale/polyfill');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (locale.toLowerCase().split('-')[0]) {
|
||||||
|
case 'af':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/af');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/af');
|
||||||
|
break;
|
||||||
|
case 'ar':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ar');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ar');
|
||||||
|
break;
|
||||||
|
case 'am':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/am');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/am');
|
||||||
|
break;
|
||||||
|
case 'an':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/an');
|
||||||
|
break;
|
||||||
|
case 'az':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/az');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/az');
|
||||||
|
break;
|
||||||
|
case 'id':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/id');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/id');
|
||||||
|
break;
|
||||||
|
case 'bn':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/bn');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/bn');
|
||||||
|
break;
|
||||||
|
case 'be':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/be');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/be');
|
||||||
|
break;
|
||||||
|
case 'bg':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/bg');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/bg');
|
||||||
|
break;
|
||||||
|
case 'ca':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ca');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ca');
|
||||||
|
break;
|
||||||
|
case 'cs':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/cs');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/cs');
|
||||||
|
break;
|
||||||
|
case 'cy':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/cy');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/cy');
|
||||||
|
break;
|
||||||
|
case 'da':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/da');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/da');
|
||||||
|
break;
|
||||||
|
case 'de':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/de');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/de');
|
||||||
|
break;
|
||||||
|
case 'et':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/et');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/et');
|
||||||
|
break;
|
||||||
|
case 'el':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/el');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/el');
|
||||||
|
break;
|
||||||
|
case 'en':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/en');
|
||||||
|
break;
|
||||||
|
case 'es':
|
||||||
|
case 'rap':
|
||||||
|
case 'qu':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/es');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/es');
|
||||||
|
break;
|
||||||
|
case 'eu':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/eu');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/eu');
|
||||||
|
break;
|
||||||
|
case 'fa':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/fa');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/fa');
|
||||||
|
break;
|
||||||
|
case 'fr':
|
||||||
|
case 'ht':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/fr');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/fr');
|
||||||
|
break;
|
||||||
|
case 'fy':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/fy');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/fy');
|
||||||
|
break;
|
||||||
|
case 'ga':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ga');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ga');
|
||||||
|
break;
|
||||||
|
case 'gd':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/gd');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/gd');
|
||||||
|
break;
|
||||||
|
case 'gl':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/gl');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/gl');
|
||||||
|
break;
|
||||||
|
case 'ko':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ko');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ko');
|
||||||
|
break;
|
||||||
|
case 'hy':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/hy');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/hy');
|
||||||
|
break;
|
||||||
|
case 'he':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/he');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/he');
|
||||||
|
break;
|
||||||
|
case 'hr':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/hr');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/hr');
|
||||||
|
break;
|
||||||
|
case 'xh':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/xh');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/xh');
|
||||||
|
break;
|
||||||
|
case 'zu':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/zu');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/zu');
|
||||||
|
break;
|
||||||
|
case 'is':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/is');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/is');
|
||||||
|
break;
|
||||||
|
case 'it':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/it');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/it');
|
||||||
|
break;
|
||||||
|
case 'ka':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ka');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ka');
|
||||||
|
break;
|
||||||
|
case 'kk':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/kk');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/kk');
|
||||||
|
break;
|
||||||
|
case 'sw':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/sw');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/sw');
|
||||||
|
break;
|
||||||
|
case 'ku':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ku');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ku');
|
||||||
|
break;
|
||||||
|
case 'ckb':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ckb');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ckb');
|
||||||
|
break;
|
||||||
|
case 'lv':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/lv');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/lv');
|
||||||
|
break;
|
||||||
|
case 'lt':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/lt');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/lt');
|
||||||
|
break;
|
||||||
|
case 'hu':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/hu');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/hu');
|
||||||
|
break;
|
||||||
|
case 'mi':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/mi');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/en');
|
||||||
|
break;
|
||||||
|
case 'mn':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/mn');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/mn');
|
||||||
|
break;
|
||||||
|
case 'nl':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/nl');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/nl');
|
||||||
|
break;
|
||||||
|
case 'ja':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ja');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ja');
|
||||||
|
break;
|
||||||
|
case 'nb':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/nb');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/nb');
|
||||||
|
break;
|
||||||
|
case 'nn':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/nn');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/nn');
|
||||||
|
break;
|
||||||
|
case 'or':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/or');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/or');
|
||||||
|
break;
|
||||||
|
case 'uz':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/uz');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/uz');
|
||||||
|
break;
|
||||||
|
case 'th':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/th');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/th');
|
||||||
|
break;
|
||||||
|
case 'km':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/km');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/km');
|
||||||
|
break;
|
||||||
|
case 'pl':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/pl');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/pl');
|
||||||
|
break;
|
||||||
|
case 'pt':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/pt');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/pt');
|
||||||
|
break;
|
||||||
|
case 'ro':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ro');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ro');
|
||||||
|
break;
|
||||||
|
case 'ru':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/ru');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/ru');
|
||||||
|
break;
|
||||||
|
case 'nso':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/nso');
|
||||||
|
break;
|
||||||
|
case 'tn':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/tn');
|
||||||
|
break;
|
||||||
|
case 'sk':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/sk');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/sk');
|
||||||
|
break;
|
||||||
|
case 'sl':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/sl');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/sl');
|
||||||
|
break;
|
||||||
|
case 'sr':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/sr');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/sr');
|
||||||
|
break;
|
||||||
|
case 'fi':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/fi');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/fi');
|
||||||
|
break;
|
||||||
|
case 'sv':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/sv');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/sv');
|
||||||
|
break;
|
||||||
|
case 'vi':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/vi');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/vi');
|
||||||
|
break;
|
||||||
|
case 'tr':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/tr');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/tr');
|
||||||
|
break;
|
||||||
|
case 'uk':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/uk');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/uk');
|
||||||
|
break;
|
||||||
|
case 'zh':
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/zh');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/zh');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
await import('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||||
|
await import('@formatjs/intl-pluralrules/locale-data/en');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default intlPolyfill;
|
|
@ -1,20 +0,0 @@
|
||||||
// this file should only be `required` in the format-time
|
|
||||||
// when Intl.RelativeTimeFormat is not available (Safari < 14), but
|
|
||||||
// we're not currently able to do the code splitting in www, and it
|
|
||||||
// is always included. To reduce the amount of data that's loaded limit
|
|
||||||
// the number of languages loaded to just the top few that are still using
|
|
||||||
// safari <14. These seven account for most uses.
|
|
||||||
// relativetimeformat depends on locale which also needs to be polyfilled in
|
|
||||||
// safari <14
|
|
||||||
// The plural rules is required for safari 12.
|
|
||||||
require('@formatjs/intl-locale/polyfill');
|
|
||||||
require('@formatjs/intl-pluralrules/polyfill');
|
|
||||||
require('@formatjs/intl-pluralrules/locale-data/en');
|
|
||||||
require('@formatjs/intl-relativetimeformat/polyfill');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/en');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/ar');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/es');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/fr');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/ja');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/tr');
|
|
||||||
require('@formatjs/intl-relativetimeformat/locale-data/zh');
|
|
|
@ -14,7 +14,14 @@ const About = () => (
|
||||||
|
|
||||||
<div className="masthead">
|
<div className="masthead">
|
||||||
<div>
|
<div>
|
||||||
<p><FormattedMessage id="about.introOne" /></p>
|
<p><FormattedMessage
|
||||||
|
id="about.introOne"
|
||||||
|
values={{foundationLink: (
|
||||||
|
<a href="https://www.scratchfoundation.org/">
|
||||||
|
<FormattedMessage id="about.foundationText" />
|
||||||
|
</a>
|
||||||
|
)}}
|
||||||
|
/></p>
|
||||||
<p><FormattedMessage id="about.introTwo" /></p>
|
<p><FormattedMessage id="about.introTwo" /></p>
|
||||||
<p><FormattedMessage id="about.introThree" /></p>
|
<p><FormattedMessage id="about.introThree" /></p>
|
||||||
|
|
||||||
|
@ -64,7 +71,8 @@ const About = () => (
|
||||||
<p><FormattedMessage
|
<p><FormattedMessage
|
||||||
id="about.aroundTheWorldDescription"
|
id="about.aroundTheWorldDescription"
|
||||||
values={{
|
values={{
|
||||||
languageCount: 60,
|
countryCount: 200,
|
||||||
|
languageCount: 70,
|
||||||
translationLink: (
|
translationLink: (
|
||||||
<a
|
<a
|
||||||
href="https://github.com/LLK/scratch-l10n/wiki/Guide-for-Scratch-Translators"
|
href="https://github.com/LLK/scratch-l10n/wiki/Guide-for-Scratch-Translators"
|
||||||
|
@ -126,11 +134,6 @@ const About = () => (
|
||||||
<FormattedMessage id="about.researchLinkText" />
|
<FormattedMessage id="about.researchLinkText" />
|
||||||
</a>
|
</a>
|
||||||
),
|
),
|
||||||
spfaLink: (
|
|
||||||
<a href="http://web.media.mit.edu/~mres/papers/Scratch-CACM-final.pdf">
|
|
||||||
<FormattedMessage id="about.spfaLinkText" />
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
lifelongKindergartenGroupLink: (
|
lifelongKindergartenGroupLink: (
|
||||||
<a href="https://www.media.mit.edu/groups/lifelong-kindergarten/overview/">
|
<a href="https://www.media.mit.edu/groups/lifelong-kindergarten/overview/">
|
||||||
<FormattedMessage id="about.lifelongKindergartenGroupLinkText" />
|
<FormattedMessage id="about.lifelongKindergartenGroupLinkText" />
|
||||||
|
@ -171,9 +174,6 @@ const About = () => (
|
||||||
<li>
|
<li>
|
||||||
<h3><FormattedMessage id="about.learnMore" /></h3>
|
<h3><FormattedMessage id="about.learnMore" /></h3>
|
||||||
<ul className="list">
|
<ul className="list">
|
||||||
<li>
|
|
||||||
<a href="/ideas"><FormattedMessage id="about.learnMoreHelp" /></a>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href="/faq"><FormattedMessage id="about.learnMoreFaq" /></a>
|
<a href="/faq"><FormattedMessage id="about.learnMoreFaq" /></a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -181,7 +181,7 @@ const About = () => (
|
||||||
<a href="/parents"><FormattedMessage id="about.learnMoreParents" /></a>
|
<a href="/parents"><FormattedMessage id="about.learnMoreParents" /></a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/credits"><FormattedMessage id="about.learnMoreCredits" /></a>
|
<a href="/educators"><FormattedMessage id="about.learnMoreEducators" /></a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/annual-report"><FormattedMessage id="about.learnMoreAnnualReport" /></a>
|
<a href="/annual-report"><FormattedMessage id="about.learnMoreAnnualReport" /></a>
|
||||||
|
@ -203,11 +203,6 @@ const About = () => (
|
||||||
<FormattedMessage id="about.donorsLinkText" />
|
<FormattedMessage id="about.donorsLinkText" />
|
||||||
</a>
|
</a>
|
||||||
),
|
),
|
||||||
annualReportLink: (
|
|
||||||
<a href="/annual-report">
|
|
||||||
<FormattedMessage id="about.annualReportLinkText" />
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
donateLink: (
|
donateLink: (
|
||||||
<a
|
<a
|
||||||
href="//secure.donationpay.org/scratchfoundation/"
|
href="//secure.donationpay.org/scratchfoundation/"
|
||||||
|
@ -216,11 +211,6 @@ const About = () => (
|
||||||
>
|
>
|
||||||
<FormattedMessage id="about.donateLinkText" />
|
<FormattedMessage id="about.donateLinkText" />
|
||||||
</a>
|
</a>
|
||||||
),
|
|
||||||
donateemail: (
|
|
||||||
<a href="mailto:donate@scratch.mit.edu">
|
|
||||||
donate@scratch.mit.edu
|
|
||||||
</a>
|
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/></p>
|
/></p>
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
{
|
{
|
||||||
"about.introOne": "With Scratch, you can program your own interactive stories, games, and animations — and share your creations with others in the online community.",
|
"about.introOne": "Scratch is the world’s largest coding community for children and a coding language with a simple visual interface that allows young people to create digital stories, games, and animations. Scratch is designed, developed, and moderated by the {foundationLink}, a nonprofit organization. ",
|
||||||
"about.introTwo": "Scratch helps young people learn to think creatively, reason systematically, and work collaboratively — essential skills for life in the 21st century.",
|
"about.introTwo": "Scratch promotes computational thinking and problem solving skills; creative teaching and learning; self-expression and collaboration; and equity in computing.",
|
||||||
"about.introThree": "Scratch is designed, developed, and moderated by the Scratch Foundation, a nonprofit organization. It is provided free of charge.",
|
"about.introThree": "Scratch is always free and is available in more than 70 languages.",
|
||||||
|
"about.foundationText": "Scratch Foundation",
|
||||||
"about.introParents": "Info for parents",
|
"about.introParents": "Info for parents",
|
||||||
"about.introEducators": "Info for educators",
|
"about.introEducators": "Info for educators",
|
||||||
"about.whoUsesScratch": "Who Uses Scratch?",
|
"about.whoUsesScratch": "Who Uses Scratch?",
|
||||||
"about.whoUsesScratchDescription": "Scratch is designed especially for ages 8 to 16, but is used by people of all ages. Millions of people are creating Scratch projects in a wide variety of settings, including homes, schools, museums, libraries, and community centers.",
|
"about.whoUsesScratchDescription": "Scratch is designed especially for ages 8 to 16, but is used by people of all ages. Millions of people are creating Scratch projects in a wide variety of settings, including homes, schools, museums, libraries, and community centers.",
|
||||||
"about.aroundTheWorld": "Around the World",
|
"about.aroundTheWorld": "Around the World",
|
||||||
"about.aroundTheWorldDescription": "Scratch is used in more than 150 different countries and available in more than {languageCount} languages. To change languages, click the menu at the bottom of the page. Or, in the Project Editor, click the globe at the top of the page. To add or improve a translation, see the {translationLink} page.",
|
"about.aroundTheWorldDescription": "Scratch is used in more than {countryCount} different countries and territories and is available in more than {languageCount} languages. To change languages, click the menu at the bottom of the page. Or, in the Project Editor, click the globe at the top of the page. To add or improve a translation, see the {translationLink} page.",
|
||||||
"about.translationLinkText": "translation",
|
"about.translationLinkText": "translation",
|
||||||
"about.quotes": "Quotes",
|
"about.quotes": "Quotes",
|
||||||
"about.quotesDescription": "The Scratch Team has received many emails from youth, parents, and educators expressing thanks for Scratch. Want to see what people are saying? You can read a collection of the {quotesLink} we've received.",
|
"about.quotesDescription": "The Scratch Team has received many emails from youth, parents, and educators expressing thanks for Scratch. Want to see what people are saying? You can read a collection of the {quotesLink} we've received.",
|
||||||
"about.quotesLinkText": "quotes",
|
"about.quotesLinkText": "quotes",
|
||||||
"about.learnMore": "Learn More About Scratch",
|
"about.learnMore": "Learn More About Scratch",
|
||||||
"about.learnMoreHelp": "Ideas Page",
|
|
||||||
"about.learnMoreFaq": "Frequently Asked Questions",
|
"about.learnMoreFaq": "Frequently Asked Questions",
|
||||||
"about.learnMoreParents": "Information for Parents",
|
"about.learnMoreParents": "Information for Parents",
|
||||||
"about.learnMoreCredits": "Our Team",
|
"about.learnMoreEducators": "Information for Educators",
|
||||||
"about.learnMoreAnnualReport": "Annual Report 2019",
|
"about.learnMoreAnnualReport": "Annual Report",
|
||||||
"about.literacy": "Learn to Code, Code to Learn",
|
"about.literacy": "Learn to Code, Code to Learn",
|
||||||
"about.literacyDescription": "The ability to code computer programs is an important part of literacy in today’s society. When people learn to code in Scratch, they learn important strategies for solving problems, designing projects, and communicating ideas.",
|
"about.literacyDescription": "The ability to code computer programs is an important part of literacy in today’s society. When people learn to code in Scratch, they learn important strategies for solving problems, designing projects, and communicating ideas.",
|
||||||
"about.schools": "Scratch in Schools",
|
"about.schools": "Scratch in Schools",
|
||||||
|
@ -25,17 +25,16 @@
|
||||||
"about.scratchForEducatorsLinkText": "Scratch For Educators",
|
"about.scratchForEducatorsLinkText": "Scratch For Educators",
|
||||||
"about.scratchedLinkText": "ScratchEd website",
|
"about.scratchedLinkText": "ScratchEd website",
|
||||||
"about.research": "Research",
|
"about.research": "Research",
|
||||||
"about.researchDescription": "The {lifelongKindergartenGroupLink} and collaborators are researching how young people create, collaborate, and learn with Scratch. For an overview, see the article {codingAtACrossroadsLink} and the book {lifelongKindergartenBookLink}. To find out more about the use of Scratch, see the {statisticsLink} page and the Scratch {annualReportLink}.",
|
"about.researchDescription": "The {lifelongKindergartenGroupLink} and collaborators are {researchLink} how young people create, collaborate, and learn with Scratch. For an overview, see the article {codingAtACrossroadsLink} and the book {lifelongKindergartenBookLink}. To find out more about the use of Scratch, see the {statisticsLink} page and the Scratch {annualReportLink}.",
|
||||||
"about.spfaLinkText": "Scratch: Programming for All",
|
"about.researchLinkText": "researching",
|
||||||
"about.researchLinkText": "research",
|
|
||||||
"about.statisticsLinkText": "statistics",
|
"about.statisticsLinkText": "statistics",
|
||||||
"about.lifelongKindergartenGroupLinkText": "Lifelong Kindergarten group",
|
"about.lifelongKindergartenGroupLinkText": "Lifelong Kindergarten group",
|
||||||
"about.codingAtACrossroadsLinkText": "Coding at a Crossroads",
|
"about.codingAtACrossroadsLinkText": "Coding at a Crossroads",
|
||||||
"about.lifelongKindergartenBookLinkText": "Lifelong Kindergarten",
|
"about.lifelongKindergartenBookLinkText": "Lifelong Kindergarten",
|
||||||
"about.annualReportLinkText": "Annual Report",
|
"about.annualReportLinkText": "Annual Report",
|
||||||
"about.support": "Support and Funding",
|
"about.support": "Support and Funding",
|
||||||
"about.supportDescription": "Scratch is available for free, thanks to support from our {donorsLink}. For more information, see our {annualReportLink}. You can support Scratch by making a donation.",
|
"about.supportDescription": "Scratch is available for free, thanks to support from our {donorsLink}. This support helps us provide kids around the world with opportunities to imagine, create, and share. You can support Scratch by making a donation {donateLink}.",
|
||||||
"about.donorsLinkText": "donors",
|
"about.donorsLinkText": "donors",
|
||||||
"about.donateLinkText": "donations page",
|
"about.donateLinkText": "here",
|
||||||
"about.donateButton": "Donate"
|
"about.donateButton": "Donate"
|
||||||
}
|
}
|
||||||
|
|
703
static/js/polyfill.min.js
vendored
703
static/js/polyfill.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,89 +0,0 @@
|
||||||
const SeleniumHelper = require('../selenium-helpers.js');
|
|
||||||
const helper = new SeleniumHelper();
|
|
||||||
|
|
||||||
var tap = require('tap');
|
|
||||||
const test = tap.test;
|
|
||||||
|
|
||||||
const webdriver = require('selenium-webdriver');
|
|
||||||
const driver = helper.buildDriver('www-smoke test-login-failures');
|
|
||||||
|
|
||||||
const {
|
|
||||||
findByCss,
|
|
||||||
clickCss
|
|
||||||
} = helper;
|
|
||||||
|
|
||||||
var until = webdriver.until;
|
|
||||||
|
|
||||||
var username = process.env.SMOKE_USERNAME;
|
|
||||||
var password = process.env.SMOKE_PASSWORD;
|
|
||||||
|
|
||||||
var rootUrl = process.env.ROOT_URL || 'https://scratch.ly';
|
|
||||||
var url = rootUrl + '/users/' + username;
|
|
||||||
|
|
||||||
tap.plan(3);
|
|
||||||
|
|
||||||
tap.tearDown(function () {
|
|
||||||
driver.quit();
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.beforeEach(function () {
|
|
||||||
return driver.get(url);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Trying to sign in with no password using scratchr2 navbar', t => {
|
|
||||||
var nonsenseusername = Math.random().toString(36)
|
|
||||||
.replace(/[^a-z]+/g, '')
|
|
||||||
.substr(0, 5);
|
|
||||||
clickCss('.dropdown-toggle')
|
|
||||||
.then(() => findByCss('form#login input#login_dropdown_username'))
|
|
||||||
.then((element) => element.sendKeys(nonsenseusername))
|
|
||||||
.then(() => clickCss('form#login button'))
|
|
||||||
.then(() => findByCss('form#login .error'))
|
|
||||||
.then((element) => {
|
|
||||||
driver.wait(until.elementIsVisible(element));
|
|
||||||
return element;
|
|
||||||
})
|
|
||||||
.then((element) => element.getText())
|
|
||||||
.then((text) => t.match(text, 'This field is required',
|
|
||||||
'"This field is required" error should be displayed'))
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Trying to sign in with the wrong username using scratchr2 navbar', t => {
|
|
||||||
var nonsenseusername = Math.random().toString(36)
|
|
||||||
.replace(/[^a-z]+/g, '')
|
|
||||||
.substr(0, 5);
|
|
||||||
clickCss('.dropdown-toggle')
|
|
||||||
.then(() => findByCss('form#login input#login_dropdown_username'))
|
|
||||||
.then((element) => element.sendKeys(nonsenseusername))
|
|
||||||
.then(() => findByCss('form#login input.wide.password'))
|
|
||||||
.then((element) => element.sendKeys(password))
|
|
||||||
.then(() => clickCss('form#login button'))
|
|
||||||
.then(() => findByCss('form#login .error'))
|
|
||||||
.then((element) => {
|
|
||||||
driver.wait(until.elementIsVisible(element));
|
|
||||||
return element;
|
|
||||||
})
|
|
||||||
.then((element) => element.getText())
|
|
||||||
.then((text) => t.match(text, 'Incorrect username or password.',
|
|
||||||
'"Incorrect username or password" error should be displayed'))
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Trying to sign in with the wrong password using scratchr2 navbar', t => {
|
|
||||||
clickCss('.dropdown-toggle')
|
|
||||||
.then(() => findByCss('form#login input#login_dropdown_username'))
|
|
||||||
.then((element) => element.sendKeys(username))
|
|
||||||
.then(() => findByCss('form#login input.wide.password'))
|
|
||||||
.then((element) => element.sendKeys('nonsensepassword'))
|
|
||||||
.then(() => clickCss('form#login button'))
|
|
||||||
.then(() => findByCss('form#login .error'))
|
|
||||||
.then((element) => {
|
|
||||||
driver.wait(until.elementIsVisible(element));
|
|
||||||
return element;
|
|
||||||
})
|
|
||||||
.then((element) => element.getText())
|
|
||||||
.then((text) => t.match(text, 'Incorrect username or password.',
|
|
||||||
'"Incorrect username or password" error should be displayed'))
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Checks the behavior of the search interface
|
|
||||||
*/
|
|
||||||
require('chromedriver');
|
|
||||||
const seleniumWebdriver = require('selenium-webdriver');
|
|
||||||
const SeleniumHelper = require('../selenium-helpers.js');
|
|
||||||
const helper = new SeleniumHelper();
|
|
||||||
const {
|
|
||||||
urlMatches
|
|
||||||
} = helper;
|
|
||||||
|
|
||||||
const tap = require('tap');
|
|
||||||
const test = tap.test;
|
|
||||||
|
|
||||||
// Set test url through environment variable
|
|
||||||
const rootUrl = process.env.ROOT_URL || 'https://scratch.ly';
|
|
||||||
const searchBaseUrl = `${rootUrl}/search/`;
|
|
||||||
|
|
||||||
// chrome driver
|
|
||||||
const driver = helper.buildDriver('www-search test_search');
|
|
||||||
|
|
||||||
tap.plan(3);
|
|
||||||
|
|
||||||
tap.tearDown(function () {
|
|
||||||
driver.quit();
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.beforeEach(function () {
|
|
||||||
return driver.get(searchBaseUrl);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Search escapes spaces', function (t) {
|
|
||||||
const searchInput = driver.findElement(seleniumWebdriver.By.name('q'));
|
|
||||||
searchInput.sendKeys('Test search string', helper.getKey('ENTER')).then(function () {
|
|
||||||
urlMatches(/^.*\?q=Test%20search%20string$/)
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Search escapes symbols', function (t) {
|
|
||||||
const searchInput = driver.findElement(seleniumWebdriver.By.name('q'));
|
|
||||||
searchInput.sendKeys('100% pen', helper.getKey('ENTER')).then(function () {
|
|
||||||
urlMatches(/^.*\?q=100%25%20pen$/)
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Switching to studios maintains search string', function (t) {
|
|
||||||
const searchInput = driver.findElement(seleniumWebdriver.By.name('q'));
|
|
||||||
searchInput.sendKeys('100% pen', helper.getKey('ENTER')).then(function () {
|
|
||||||
const studiosTab = driver.findElement(seleniumWebdriver.By.xpath(
|
|
||||||
'//a/li/span[contains(text(),"Studios")]'));
|
|
||||||
studiosTab.click().then(function () {
|
|
||||||
urlMatches(/^.*\?q=100%25%20pen$/)
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Tests stats page according to smoke-tests at:
|
|
||||||
*
|
|
||||||
* https://github.com/LLK/scratchr2/wiki/Smoke-Testing-Test-Cases
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
const SeleniumHelper = require('../selenium-helpers.js');
|
|
||||||
const helper = new SeleniumHelper();
|
|
||||||
|
|
||||||
var tap = require('tap');
|
|
||||||
const test = tap.test;
|
|
||||||
|
|
||||||
const driver = helper.buildDriver('www-smoke test_statistics_page');
|
|
||||||
|
|
||||||
const {
|
|
||||||
clickText,
|
|
||||||
findByXpath,
|
|
||||||
findByCss
|
|
||||||
} = helper;
|
|
||||||
|
|
||||||
tap.plan(2);
|
|
||||||
|
|
||||||
tap.tearDown(function () {
|
|
||||||
driver.quit();
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.beforeEach(function () {
|
|
||||||
/*
|
|
||||||
* load the page with the driver
|
|
||||||
* note that for now this is not testable on Staging,
|
|
||||||
* so I left it pointing to Production -
|
|
||||||
* we can at least use it post-deploy.
|
|
||||||
*
|
|
||||||
* var stagingURL = 'https://scratch.ly/statistics';
|
|
||||||
*/
|
|
||||||
var productionURL = 'https://scratch.mit.edu/statistics';
|
|
||||||
return driver.get(productionURL);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('check that Monthly Activity Trends title is present & correct', t => {
|
|
||||||
var chartTitle = 'Monthly Activity Trends';
|
|
||||||
findByCss('div.box-head h3')
|
|
||||||
.then((element) => element.getText('h3'))
|
|
||||||
.then((text) => t.equal(text, chartTitle, 'chart title should be Monthly Activity Trends'))
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
||||||
|
|
||||||
test('check that Monthly Activity Trends chart > New Projects label is toggleable', t => {
|
|
||||||
var classXpath = `(//div[@id="activity_chart"]/*[name()='svg']/*[name()='g']/*[name()='g']/*` +
|
|
||||||
`[name()='g'])[4]/*[name()='g']/*[name()='g']/*[name()='g']`;
|
|
||||||
findByXpath(classXpath)
|
|
||||||
.then((element) => element.getAttribute('class'))
|
|
||||||
.then((classtext) => t.equal(classtext, 'nv-series', 'by default, New Projects should be enabled'))
|
|
||||||
.then(() => clickText('New Projects'))
|
|
||||||
.then(() => findByXpath(classXpath))
|
|
||||||
.then((element) => element.getAttribute('class'))
|
|
||||||
.then((classtext) => t.equal(
|
|
||||||
classtext,
|
|
||||||
'nv-series nv-disabled',
|
|
||||||
'when clicked, New Projects should be disabled'
|
|
||||||
))
|
|
||||||
.then(() => clickText('New Projects'))
|
|
||||||
.then(() => findByXpath(classXpath))
|
|
||||||
.then((element) => element.getAttribute('class'))
|
|
||||||
.then((classtext) => t.equal(classtext, 'nv-series', 'when clicked again, New Projects should be enabled'))
|
|
||||||
.then(() => t.end());
|
|
||||||
});
|
|
|
@ -40,6 +40,7 @@ let profileComment = buildNumber + ' profile';
|
||||||
let studioComment = buildNumber + ' studio';
|
let studioComment = buildNumber + ' studio';
|
||||||
|
|
||||||
let projectReply = projectComment + ' reply';
|
let projectReply = projectComment + ' reply';
|
||||||
|
let profileReply = profileComment + ' reply';
|
||||||
let studioReply = studioComment + ' reply';
|
let studioReply = studioComment + ' reply';
|
||||||
|
|
||||||
if (remote) {
|
if (remote) {
|
||||||
|
@ -284,6 +285,24 @@ describe('comment tests', async () => {
|
||||||
await expect(commentVisible).toBe(true);
|
await expect(commentVisible).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('profile reply to comment', async () => {
|
||||||
|
await driver.get(profileUrl);
|
||||||
|
// find the comment and click reply
|
||||||
|
let commentXpath = `//div[contains(text(), "${profileComment}")]/..`;
|
||||||
|
await clickXpath(commentXpath + '//a[@class = "reply"]');
|
||||||
|
|
||||||
|
// select reply box and type reply
|
||||||
|
let replyComposeBox = await findByXpath(commentXpath + '//textArea');
|
||||||
|
await replyComposeBox.sendKeys(profileReply);
|
||||||
|
|
||||||
|
// click post
|
||||||
|
await clickXpath(commentXpath + '//a[contains(text(), "Post")]');
|
||||||
|
|
||||||
|
// reload the page step has been skipped because caching causes failure
|
||||||
|
// The reply wasn't findable by xpath after several attempts, but it seems
|
||||||
|
// better to have this much of a test
|
||||||
|
});
|
||||||
|
|
||||||
test('studio: reply to comment', async () => {
|
test('studio: reply to comment', async () => {
|
||||||
await driver.get(studioUrl);
|
await driver.get(studioUrl);
|
||||||
|
|
||||||
|
|
63
test/integration/search.test.js
Normal file
63
test/integration/search.test.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// These tests do not sign in with a user
|
||||||
|
|
||||||
|
const SeleniumHelper = require('./selenium-helpers.js');
|
||||||
|
|
||||||
|
const {
|
||||||
|
buildDriver,
|
||||||
|
clickXpath,
|
||||||
|
findByXpath,
|
||||||
|
getKey
|
||||||
|
} = new SeleniumHelper();
|
||||||
|
|
||||||
|
let remote = process.env.SMOKE_REMOTE || false;
|
||||||
|
let rootUrl = process.env.ROOT_URL || 'https://scratch.ly';
|
||||||
|
|
||||||
|
if (remote){
|
||||||
|
jest.setTimeout(60000);
|
||||||
|
} else {
|
||||||
|
jest.setTimeout(20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
let driver;
|
||||||
|
|
||||||
|
describe('www-integration search', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
driver = await buildDriver('www-integration search');
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await driver.get(rootUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => await driver.quit());
|
||||||
|
|
||||||
|
test('search converts spaces', async () => {
|
||||||
|
let searchBar = await findByXpath('//div[contains(@class, "search-wrapper")]/div/input');
|
||||||
|
await searchBar.sendKeys('Test search string' + getKey('ENTER'));
|
||||||
|
|
||||||
|
// check url
|
||||||
|
let url = await driver.getCurrentUrl();
|
||||||
|
await expect(url).toMatch(/^.*\?q=Test%20search%20string$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Search escapes symbols', async () => {
|
||||||
|
let searchBar = await findByXpath('//div[contains(@class, "search-wrapper")]/div/input');
|
||||||
|
await searchBar.sendKeys('100% pen' + getKey('ENTER'));
|
||||||
|
|
||||||
|
// check url
|
||||||
|
let url = await driver.getCurrentUrl();
|
||||||
|
await expect(url).toMatch(/^.*\?q=100%25%20pen$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Switching to studios maintains search string', async () => {
|
||||||
|
let searchBar = await findByXpath('//div[contains(@class, "search-wrapper")]/div/input');
|
||||||
|
await searchBar.sendKeys('100% pen' + getKey('ENTER'));
|
||||||
|
|
||||||
|
// switch to studios tab
|
||||||
|
clickXpath('//a/li/span[contains(text(),"Studios")]');
|
||||||
|
|
||||||
|
// check url
|
||||||
|
let url = await driver.getCurrentUrl();
|
||||||
|
await expect(url).toMatch(/^.*\?q=100%25%20pen$/);
|
||||||
|
});
|
||||||
|
});
|
|
@ -199,6 +199,10 @@ class SeleniumHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async waitUntilVisible (element, driver) {
|
||||||
|
await driver.wait(until.elementIsVisible(element));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SeleniumHelper;
|
module.exports = SeleniumHelper;
|
||||||
|
|
|
@ -7,7 +7,9 @@ const {
|
||||||
findByXpath,
|
findByXpath,
|
||||||
clickXpath,
|
clickXpath,
|
||||||
clickButton,
|
clickButton,
|
||||||
buildDriver
|
buildDriver,
|
||||||
|
signIn,
|
||||||
|
waitUntilVisible
|
||||||
} = new SeleniumHelper();
|
} = new SeleniumHelper();
|
||||||
|
|
||||||
let username = process.env.SMOKE_USERNAME;
|
let username = process.env.SMOKE_USERNAME;
|
||||||
|
@ -30,6 +32,10 @@ describe('www-integration sign-in-and-out', () => {
|
||||||
driver = await buildDriver('www-integration sign-in-out');
|
driver = await buildDriver('www-integration sign-in-out');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await driver.quit();
|
||||||
|
});
|
||||||
|
|
||||||
describe('sign in', () => {
|
describe('sign in', () => {
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await driver.get(wwwURL);
|
await driver.get(wwwURL);
|
||||||
|
@ -71,14 +77,7 @@ describe('www-integration sign-in-and-out', () => {
|
||||||
describe('sign out', () => {
|
describe('sign out', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await driver.get(wwwURL);
|
await driver.get(wwwURL);
|
||||||
await clickXpath('//li[@class="link right login-item"]');
|
await signIn(username, password, driver);
|
||||||
let name = await findByXpath('//input[@id="frc-username-1088"]');
|
|
||||||
await name.sendKeys(username);
|
|
||||||
let word = await findByXpath('//input[@id="frc-password-1088"]');
|
|
||||||
await word.sendKeys(password);
|
|
||||||
await driver.sleep(500);
|
|
||||||
await clickXpath('//button[contains(@class, "button") and ' +
|
|
||||||
'contains(@class, "submit-button") and contains(@class, "white")]');
|
|
||||||
await driver.sleep(500);
|
await driver.sleep(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -101,8 +100,61 @@ describe('www-integration sign-in-and-out', () => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
describe('login failures', async () => {
|
||||||
await driver.quit();
|
test('sign in with no password in Scratchr2', async () => {
|
||||||
|
let nonsenseUsername = Math.random().toString(36)
|
||||||
|
.replace(/[^a-z]+/g, '')
|
||||||
|
.substr(0, 5);
|
||||||
|
await driver.get(scratchr2url);
|
||||||
|
await clickXpath('//li[@class="sign-in dropdown"]/span');
|
||||||
|
let name = await findByXpath('//input[@id="login_dropdown_username"]');
|
||||||
|
await name.sendKeys(nonsenseUsername);
|
||||||
|
await clickButton('Sign in');
|
||||||
|
|
||||||
|
// find error
|
||||||
|
let error = await findByXpath('//form[@id="login"]//div[@class="error"]');
|
||||||
|
let errorText = await error.getText();
|
||||||
|
await expect(errorText).toEqual('This field is required.');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sign in with wrong username', async () => {
|
||||||
|
let nonsenseUsername = Math.random().toString(36)
|
||||||
|
.replace(/[^a-z]+/g, '')
|
||||||
|
.substr(0, 5);
|
||||||
|
await driver.get(scratchr2url);
|
||||||
|
await clickXpath('//li[@class="sign-in dropdown"]/span');
|
||||||
|
let name = await findByXpath('//input[@id="login_dropdown_username"]');
|
||||||
|
await name.sendKeys(nonsenseUsername);
|
||||||
|
let word = await findByXpath('//input[@name="password"]');
|
||||||
|
await word.sendKeys(password);
|
||||||
|
await clickButton('Sign in');
|
||||||
|
|
||||||
|
// find error
|
||||||
|
let error = await findByXpath('//form[@id="login"]//div[@class="error"]');
|
||||||
|
await waitUntilVisible(error, driver);
|
||||||
|
let errorText = await error.getText();
|
||||||
|
await expect(errorText).toEqual('Incorrect username or password.');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sign in with wrong password', async () => {
|
||||||
|
let nonsensePassword = Math.random().toString(36)
|
||||||
|
.replace(/[^a-z]+/g, '')
|
||||||
|
.substr(0, 5);
|
||||||
|
await driver.get(scratchr2url);
|
||||||
|
await clickXpath('//li[@class="sign-in dropdown"]/span');
|
||||||
|
let name = await findByXpath('//input[@id="login_dropdown_username"]');
|
||||||
|
await name.sendKeys(username);
|
||||||
|
let word = await findByXpath('//input[@name="password"]');
|
||||||
|
await word.sendKeys(nonsensePassword);
|
||||||
|
await clickButton('Sign in');
|
||||||
|
|
||||||
|
// find error
|
||||||
|
let error = await findByXpath('//form[@id="login"]//div[@class="error"]');
|
||||||
|
await waitUntilVisible(error, driver);
|
||||||
|
let errorText = await error.getText();
|
||||||
|
await expect(errorText).toEqual('Incorrect username or password.');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
66
test/integration/statistics.test.js
Normal file
66
test/integration/statistics.test.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// these tests do not sign in as a user
|
||||||
|
|
||||||
|
const SeleniumHelper = require('./selenium-helpers.js');
|
||||||
|
|
||||||
|
const {
|
||||||
|
buildDriver,
|
||||||
|
clickText,
|
||||||
|
containsClass,
|
||||||
|
findByXpath
|
||||||
|
} = new SeleniumHelper();
|
||||||
|
|
||||||
|
let remote = process.env.SMOKE_REMOTE || false;
|
||||||
|
let rootUrl = process.env.ROOT_URL || 'https://scratch.ly';
|
||||||
|
let statisticsPage = rootUrl + '/statistics';
|
||||||
|
|
||||||
|
if (remote) {
|
||||||
|
jest.setTimeout(60000);
|
||||||
|
} else {
|
||||||
|
jest.setTimeout(10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
let driver;
|
||||||
|
|
||||||
|
describe('www-integration statistics page', async () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
driver = await buildDriver('www-integration statistics page');
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await driver.get(statisticsPage);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => await driver.quit());
|
||||||
|
|
||||||
|
test('check Monthly Activity Trends title', async () => {
|
||||||
|
let chartTitle = await findByXpath('//div[contains(@class, "box0")]//h3');
|
||||||
|
let chartTitleText = await chartTitle.getText();
|
||||||
|
await expect(chartTitleText).toBe('Monthly Activity Trends');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('New Projects label on first chart defaults to selected', async () => {
|
||||||
|
let toggleXpath = `(//div[@id="activity_chart"]/*[name()='svg']/*[name()='g']/*[name()='g']/*` +
|
||||||
|
`[name()='g'])[4]/*[name()='g']/*[name()='g']/*[name()='g']`;
|
||||||
|
let newProjectsToggle = await findByXpath(toggleXpath);
|
||||||
|
let toggleState = await containsClass(newProjectsToggle, 'nv-disabled');
|
||||||
|
await expect(toggleState).toBe(false);
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test('New Projects label on first chart can be toggled', async () => {
|
||||||
|
let toggleXpath = `(//div[@id="activity_chart"]/*[name()='svg']/*[name()='g']/*[name()='g']/*` +
|
||||||
|
`[name()='g'])[4]/*[name()='g']/*[name()='g']/*[name()='g']`;
|
||||||
|
let newProjectsToggle = await findByXpath(toggleXpath);
|
||||||
|
|
||||||
|
// toggle off New Projects
|
||||||
|
await clickText('New Projects');
|
||||||
|
let toggleState = await containsClass(newProjectsToggle, 'nv-disabled');
|
||||||
|
await expect(toggleState).toBe(true);
|
||||||
|
|
||||||
|
// toggle New Projects on again
|
||||||
|
await clickText('New Projects');
|
||||||
|
toggleState = await containsClass(newProjectsToggle, 'nv-disabled');
|
||||||
|
await expect(toggleState).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue