@robotical/martyblocksjr 4.2.10 → 4.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/editions/free/src/30d09ba32a17082ef820.hex +26350 -0
- package/editions/free/src/app.bundle.js +1 -1
- package/editions/free/src/app.bundle.js.LICENSE.txt +15 -0
- package/editions/free/src/assets/blockicons/microbitbuttona.svg +7 -1
- package/editions/free/src/assets/blockicons/microbitbuttonab.svg +8 -1
- package/editions/free/src/assets/blockicons/microbitbuttonb.svg +7 -1
- package/editions/free/src/assets/blockicons/microbitdisplayclear.svg +9 -25
- package/editions/free/src/assets/blockicons/microbitdisplayhappy.svg +13 -31
- package/editions/free/src/assets/blockicons/microbitdisplayheart.svg +13 -37
- package/editions/free/src/assets/blockicons/microbitdisplaytext.svg +10 -25
- package/editions/free/src/assets/blockicons/microbittiltleft.svg +1 -1
- package/editions/free/src/assets/blockicons/microbittiltright.svg +1 -1
- package/editions/free/src/assets/connection/remove_extension-default.svg +5 -0
- package/editions/free/src/css/editor.css +171 -5
- package/editions/free/src/css/editorleftpanel.css +87 -12
- package/editions/free/src/localizations/bg.json +12 -12
- package/editions/free/src/localizations/ca.json +12 -12
- package/editions/free/src/localizations/cs.json +12 -12
- package/editions/free/src/localizations/cy.json +12 -12
- package/editions/free/src/localizations/da.json +12 -12
- package/editions/free/src/localizations/de.json +12 -12
- package/editions/free/src/localizations/el.json +12 -12
- package/editions/free/src/localizations/en.json +34 -14
- package/editions/free/src/localizations/es.json +12 -12
- package/editions/free/src/localizations/fi.json +12 -12
- package/editions/free/src/localizations/fr.json +12 -12
- package/editions/free/src/localizations/it.json +12 -12
- package/editions/free/src/localizations/ja.json +12 -12
- package/editions/free/src/localizations/ko.json +12 -12
- package/editions/free/src/localizations/nl.json +12 -12
- package/editions/free/src/localizations/no.json +12 -12
- package/editions/free/src/localizations/pl.json +12 -12
- package/editions/free/src/localizations/pt-br.json +12 -12
- package/editions/free/src/localizations/pt.json +12 -12
- package/editions/free/src/localizations/sv.json +12 -12
- package/editions/free/src/localizations/th.json +12 -12
- package/editions/free/src/localizations/tr.json +12 -12
- package/editions/free/src/localizations/uk.json +12 -12
- package/editions/free/src/localizations/zh-cn.json +12 -12
- package/editions/free/src/localizations/zh-tw.json +12 -12
- package/package.json +4 -1
- package/scripts/prepare-microbit-hex.mjs +47 -0
- package/tests/BlockGuideRegistry.test.js +4 -2
- package/tests/MicroBitBlockDescriptions.test.js +28 -0
- package/tests/MicroBitBlockOptions.test.js +34 -0
- package/tests/MicroBitButtonIcons.test.js +24 -0
- package/tests/MicroBitDisplayIcons.test.js +64 -0
- package/tests/e2e/chromium-79-smoke.test.js +126 -10
- package/tests/e2e/marty-connection-ui.e2e.test.js +152 -4
- package/tests/e2e/microbit-updater.test.js +126 -0
- package/vitest.config.js +1 -0
- package/webpack.config.js +4 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import {createHash} from 'node:crypto';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import {createRequire} from 'node:module';
|
|
5
|
+
import {fileURLToPath} from 'node:url';
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const JSZip = require('jszip');
|
|
9
|
+
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const projectRoot = path.resolve(__dirname, '..');
|
|
12
|
+
const sourceUrl = 'https://downloads.scratch.mit.edu/microbit/scratch-microbit.hex.zip';
|
|
13
|
+
const outputPath = path.join(projectRoot, 'src', 'assets', 'microbit', 'scratch-microbit.hex');
|
|
14
|
+
const expectedHexSha256 = '6a0cc7c2927ef53c8a8e8e26b8df06778f0a9896af49a98b285f51fff58c53e2';
|
|
15
|
+
|
|
16
|
+
async function prepareMicroBitHex () {
|
|
17
|
+
console.info(`Downloading ${sourceUrl}`);
|
|
18
|
+
const response = await fetch(sourceUrl);
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
throw new Error(`Could not download the micro:bit HEX archive: HTTP ${response.status}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const archive = new JSZip(Buffer.from(await response.arrayBuffer()));
|
|
24
|
+
const hexEntryName = Object.keys(archive.files).find(fileName =>
|
|
25
|
+
!archive.files[fileName].dir && /\.hex$/i.test(fileName)
|
|
26
|
+
);
|
|
27
|
+
if (!hexEntryName) {
|
|
28
|
+
throw new Error('The micro:bit HEX archive did not contain a HEX file.');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const hexData = archive.file(hexEntryName).asNodeBuffer();
|
|
32
|
+
const actualHexSha256 = createHash('sha256').update(hexData).digest('hex');
|
|
33
|
+
if (actualHexSha256 !== expectedHexSha256) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`The downloaded micro:bit HEX failed its integrity check. ` +
|
|
36
|
+
`Expected ${expectedHexSha256}, received ${actualHexSha256}.`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
await fs.mkdir(path.dirname(outputPath), {recursive: true});
|
|
40
|
+
await fs.writeFile(outputPath, hexData);
|
|
41
|
+
console.info(`Wrote ${path.relative(projectRoot, outputPath)}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
prepareMicroBitHex().catch(error => {
|
|
45
|
+
console.error(error);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
});
|
|
@@ -31,7 +31,7 @@ describe('Blocks Guide registry', () => {
|
|
|
31
31
|
const documentedIds = new Set(getDocumentedBlockIds());
|
|
32
32
|
|
|
33
33
|
expect([...documentedIds].sort()).toEqual([...expectedIds].sort());
|
|
34
|
-
expect(documentedIds.size).toBe(
|
|
34
|
+
expect(documentedIds.size).toBe(88);
|
|
35
35
|
expect(Object.keys(BLOCK_GUIDE_METADATA).sort()).toEqual([...expectedIds].sort());
|
|
36
36
|
});
|
|
37
37
|
|
|
@@ -47,7 +47,7 @@ describe('Blocks Guide registry', () => {
|
|
|
47
47
|
expect(BLOCK_GUIDE_MODES[2].categories.map((category) => category.id)).toEqual(
|
|
48
48
|
['start', 'looks', 'sound']
|
|
49
49
|
);
|
|
50
|
-
expect(BLOCK_GUIDE_EXTENSION.blockCount).toBe(
|
|
50
|
+
expect(BLOCK_GUIDE_EXTENSION.blockCount).toBe(7);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
it('provides visible copy and artwork for every documented block', () => {
|
|
@@ -56,5 +56,7 @@ describe('Blocks Guide registry', () => {
|
|
|
56
56
|
expect(item.description, `${blockId} description`).toBeTruthy();
|
|
57
57
|
expect(Boolean(item.icon || item.symbol), `${blockId} artwork`).toBe(true);
|
|
58
58
|
});
|
|
59
|
+
expect(BLOCK_GUIDE_METADATA.microbittilted.icon)
|
|
60
|
+
.toBe('../assets/blockicons/microbittiltright.svg');
|
|
59
61
|
});
|
|
60
62
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import englishMessages from '../editions/free/src/localizations/en.json';
|
|
3
|
+
|
|
4
|
+
describe('micro:bit block descriptions', () => {
|
|
5
|
+
it('uses concise palette and accessibility labels', () => {
|
|
6
|
+
expect({
|
|
7
|
+
cogButton: englishMessages.BLOCK_DESC_ON_TOUCH_Cog,
|
|
8
|
+
button: englishMessages.BLOCK_DESC_MICROBIT_ON_BUTTON,
|
|
9
|
+
gesture: englishMessages.BLOCK_DESC_MICROBIT_ON_GESTURE,
|
|
10
|
+
tilt: englishMessages.BLOCK_DESC_MICROBIT_ON_TILT,
|
|
11
|
+
heart: englishMessages.BLOCK_DESC_MICROBIT_DISPLAY_HEART,
|
|
12
|
+
happy: englishMessages.BLOCK_DESC_MICROBIT_DISPLAY_HAPPY,
|
|
13
|
+
text: englishMessages.BLOCK_DESC_MICROBIT_DISPLAY_TEXT,
|
|
14
|
+
custom: englishMessages.BLOCK_DESC_MICROBIT_DISPLAY_CUSTOM,
|
|
15
|
+
clear: englishMessages.BLOCK_DESC_MICROBIT_CLEAR_DISPLAY
|
|
16
|
+
}).toEqual({
|
|
17
|
+
cogButton: 'START ON BUTTON PRESS',
|
|
18
|
+
button: 'START ON BUTTON PRESS',
|
|
19
|
+
gesture: 'START ON GESTURE',
|
|
20
|
+
tilt: 'START ON TILT',
|
|
21
|
+
heart: 'DISPLAY HEART',
|
|
22
|
+
happy: 'DISPLAY HAPPY FACE',
|
|
23
|
+
text: 'DISPLAY TEXT',
|
|
24
|
+
custom: 'DISPLAY CUSTOM PATTERN',
|
|
25
|
+
clear: 'CLEAR DISPLAY'
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {describe, expect, it} from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
MICROBIT_DEFAULT_TILT_OPTION,
|
|
4
|
+
MICROBIT_LEGACY_TILT_ANY_OPTION,
|
|
5
|
+
MICROBIT_TILT_OPTIONS,
|
|
6
|
+
resolveMicroBitTiltIcon
|
|
7
|
+
} from '../src/microbit/MicroBitBlockOptions';
|
|
8
|
+
|
|
9
|
+
describe('micro:bit block options', () => {
|
|
10
|
+
it('offers only directional tilt choices for new blocks', () => {
|
|
11
|
+
expect(MICROBIT_TILT_OPTIONS).toEqual([
|
|
12
|
+
'microbittiltright',
|
|
13
|
+
'microbittiltleft',
|
|
14
|
+
'microbittiltbackward',
|
|
15
|
+
'microbittiltforward'
|
|
16
|
+
]);
|
|
17
|
+
expect(MICROBIT_DEFAULT_TILT_OPTION).toBe('microbittiltright');
|
|
18
|
+
expect(MICROBIT_TILT_OPTIONS).not.toContain(MICROBIT_LEGACY_TILT_ANY_OPTION);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('keeps the tilt-any artwork for legacy saved arguments', () => {
|
|
22
|
+
expect(resolveMicroBitTiltIcon('microbittiltany', MICROBIT_TILT_OPTIONS))
|
|
23
|
+
.toBe('microbittiltany');
|
|
24
|
+
expect(resolveMicroBitTiltIcon('tilt_any', MICROBIT_TILT_OPTIONS))
|
|
25
|
+
.toBe('microbittiltany');
|
|
26
|
+
expect(resolveMicroBitTiltIcon('tiltright', MICROBIT_TILT_OPTIONS))
|
|
27
|
+
.toBe('microbittiltright');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('falls back safely when an unknown tilt argument is loaded', () => {
|
|
31
|
+
expect(resolveMicroBitTiltIcon('unknown', MICROBIT_TILT_OPTIONS))
|
|
32
|
+
.toBe(MICROBIT_DEFAULT_TILT_OPTION);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {readFileSync} from 'node:fs';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {describe, expect, it} from 'vitest';
|
|
4
|
+
|
|
5
|
+
const ICON_DIRECTORY = join('editions', 'free', 'src', 'assets', 'blockicons');
|
|
6
|
+
const BUTTON_ICONS = [
|
|
7
|
+
{file: 'microbitbuttona.svg', handCount: 1},
|
|
8
|
+
{file: 'microbitbuttonb.svg', handCount: 1},
|
|
9
|
+
{file: 'microbitbuttonab.svg', handCount: 2}
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
describe('micro:bit button icons', () => {
|
|
13
|
+
BUTTON_ICONS.forEach(({file, handCount}) => {
|
|
14
|
+
it(`${file} uses hands instead of letter labels`, () => {
|
|
15
|
+
const svg = readFileSync(join(ICON_DIRECTORY, file), 'utf8');
|
|
16
|
+
const hands = svg.match(/<use href="#button-press-hand"/g) || [];
|
|
17
|
+
|
|
18
|
+
expect(svg).not.toMatch(/<text\b/);
|
|
19
|
+
expect(svg).toContain('fill="#34332b"');
|
|
20
|
+
expect(svg).toContain('fill="#fff"');
|
|
21
|
+
expect(hands).toHaveLength(handCount);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {readFileSync} from 'node:fs';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {describe, expect, it} from 'vitest';
|
|
4
|
+
|
|
5
|
+
const ASSET_DIRECTORY = join('editions', 'free', 'src', 'assets');
|
|
6
|
+
const DISPLAY_BLOCK_ASSETS = [
|
|
7
|
+
join('blockicons', 'microbitdisplayheart.svg'),
|
|
8
|
+
join('blockicons', 'microbitdisplayhappy.svg'),
|
|
9
|
+
join('blockicons', 'microbitdisplaytext.svg'),
|
|
10
|
+
join('blockicons', 'microbitdisplayclear.svg')
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
describe('micro:bit display artwork', () => {
|
|
14
|
+
DISPLAY_BLOCK_ASSETS.forEach((file) => {
|
|
15
|
+
it(`${file} uses a display-only treatment`, () => {
|
|
16
|
+
const svg = readFileSync(join(ASSET_DIRECTORY, file), 'utf8');
|
|
17
|
+
|
|
18
|
+
expect(svg).toContain('data-microbit-display="true"');
|
|
19
|
+
expect(svg).toContain('transform="translate(-5 0)"');
|
|
20
|
+
expect(svg).toContain('fill="#414757"');
|
|
21
|
+
expect(svg).not.toMatch(/#35c1df/i);
|
|
22
|
+
expect(svg).not.toMatch(/#4c97ff/i);
|
|
23
|
+
expect(svg).not.toMatch(/#ffbf00/i);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
DISPLAY_BLOCK_ASSETS.filter((file) => !file.endsWith('microbitdisplayclear.svg')).forEach((file) => {
|
|
28
|
+
it(`${file} uses white for lit LEDs`, () => {
|
|
29
|
+
const svg = readFileSync(join(ASSET_DIRECTORY, file), 'utf8');
|
|
30
|
+
|
|
31
|
+
expect(svg).toContain('#FFFFFF');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('shows clear display as a fully unlit 5x5 matrix without an X', () => {
|
|
36
|
+
const svg = readFileSync(join(ASSET_DIRECTORY, 'blockicons', 'microbitdisplayclear.svg'), 'utf8');
|
|
37
|
+
|
|
38
|
+
expect(svg.match(/rx="0\.8"/g)).toHaveLength(25);
|
|
39
|
+
expect(svg).not.toContain('data-led-state="on"');
|
|
40
|
+
expect(svg).not.toContain('#FFFFFF');
|
|
41
|
+
expect(svg).not.toContain('<path');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
['MicroBitLooksOn.svg', 'MicroBitLooksOff.svg'].forEach((file) => {
|
|
45
|
+
it(`${file} keeps the full micro:bit category artwork`, () => {
|
|
46
|
+
const svg = readFileSync(join(ASSET_DIRECTORY, 'categories', file), 'utf8');
|
|
47
|
+
|
|
48
|
+
expect(svg).not.toContain('data-microbit-display="true"');
|
|
49
|
+
expect(svg).toMatch(/#4c97ff/i);
|
|
50
|
+
expect(svg).toMatch(/#ffbf00/i);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('uses the same white LED colour for the custom preview and editor', () => {
|
|
55
|
+
const blockArg = readFileSync(join('src', 'editor', 'blocks', 'BlockArg.js'), 'utf8');
|
|
56
|
+
const editorCss = readFileSync(join('editions', 'free', 'src', 'css', 'editor.css'), 'utf8');
|
|
57
|
+
|
|
58
|
+
expect(blockArg).toContain('drawMicroBitDisplay');
|
|
59
|
+
expect(blockArg).toMatch(/drawMicroBitDisplay\(ctx,.*?, 13, 8, 49, 49\);/);
|
|
60
|
+
expect(blockArg).toContain("enabled ? '#FFFFFF' : '#7C87A5'");
|
|
61
|
+
expect(blockArg).not.toContain('drawMicroBitBoard');
|
|
62
|
+
expect(editorCss).toMatch(/\.microbitMatrixCell\.on\s*\{[^}]*background:\s*#FFFFFF;/s);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -112,6 +112,14 @@ async function openExtensionsLibrary(page) {
|
|
|
112
112
|
await page.click("#addExtensionButton");
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
async function getPaletteUndoGap(page) {
|
|
116
|
+
return page.evaluate(() => {
|
|
117
|
+
const palette = document.getElementById("palette").getBoundingClientRect();
|
|
118
|
+
const undoControls = document.getElementById("undocontrols").getBoundingClientRect();
|
|
119
|
+
return undoControls.left - palette.right;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
115
123
|
describe("Chromium 79 smoke test", () => {
|
|
116
124
|
it(
|
|
117
125
|
"loads home page without console errors",
|
|
@@ -127,7 +135,7 @@ describe("Chromium 79 smoke test", () => {
|
|
|
127
135
|
);
|
|
128
136
|
|
|
129
137
|
it(
|
|
130
|
-
"
|
|
138
|
+
"uses the third connection slot for either the extension entry or micro:bit controls",
|
|
131
139
|
async () => {
|
|
132
140
|
const { browser, page, errors } = await openPage("/editor.html?mode=edit");
|
|
133
141
|
|
|
@@ -137,6 +145,7 @@ describe("Chromium 79 smoke test", () => {
|
|
|
137
145
|
const initialState = await page.evaluate(() => {
|
|
138
146
|
const addButton = document.getElementById("addExtensionButton");
|
|
139
147
|
const microBitButton = document.getElementById("microBitConnectionButton");
|
|
148
|
+
const removeButton = document.getElementById("microBitRemoveButton");
|
|
140
149
|
return {
|
|
141
150
|
addButtonDisplay: window.getComputedStyle(addButton).display,
|
|
142
151
|
addButtonAriaHidden: addButton.getAttribute("aria-hidden"),
|
|
@@ -144,6 +153,9 @@ describe("Chromium 79 smoke test", () => {
|
|
|
144
153
|
microBitButtonDisplay: window.getComputedStyle(microBitButton).display,
|
|
145
154
|
microBitButtonAriaHidden: microBitButton.getAttribute("aria-hidden"),
|
|
146
155
|
microBitButtonDisabled: microBitButton.disabled,
|
|
156
|
+
removeButtonDisplay: window.getComputedStyle(removeButton).display,
|
|
157
|
+
removeButtonAriaHidden: removeButton.getAttribute("aria-hidden"),
|
|
158
|
+
removeButtonDisabled: removeButton.disabled,
|
|
147
159
|
rightCategoryIds: Array.from(document.querySelectorAll("#selectorsright .category-selector-button")).map(
|
|
148
160
|
(button) => button.id
|
|
149
161
|
),
|
|
@@ -158,6 +170,9 @@ describe("Chromium 79 smoke test", () => {
|
|
|
158
170
|
microBitButtonDisplay: "none",
|
|
159
171
|
microBitButtonAriaHidden: "true",
|
|
160
172
|
microBitButtonDisabled: true,
|
|
173
|
+
removeButtonDisplay: "none",
|
|
174
|
+
removeButtonAriaHidden: "true",
|
|
175
|
+
removeButtonDisabled: true,
|
|
161
176
|
rightCategoryIds: ["cog-start", "cog-looks", "cog-sound"],
|
|
162
177
|
extensionEnabled: false,
|
|
163
178
|
});
|
|
@@ -195,6 +210,8 @@ describe("Chromium 79 smoke test", () => {
|
|
|
195
210
|
const enabledState = await page.evaluate(() => {
|
|
196
211
|
const addButton = document.getElementById("addExtensionButton");
|
|
197
212
|
const microBitButton = document.getElementById("microBitConnectionButton");
|
|
213
|
+
const removeButton = document.getElementById("microBitRemoveButton");
|
|
214
|
+
const microBitAction = microBitButton.querySelector(".iconButtonContainer");
|
|
198
215
|
return {
|
|
199
216
|
addButtonDisplay: window.getComputedStyle(addButton).display,
|
|
200
217
|
addButtonAriaHidden: addButton.getAttribute("aria-hidden"),
|
|
@@ -202,6 +219,13 @@ describe("Chromium 79 smoke test", () => {
|
|
|
202
219
|
microBitButtonDisplay: window.getComputedStyle(microBitButton).display,
|
|
203
220
|
microBitButtonAriaHidden: microBitButton.getAttribute("aria-hidden"),
|
|
204
221
|
microBitButtonDisabled: microBitButton.disabled,
|
|
222
|
+
removeButtonDisplay: window.getComputedStyle(removeButton).display,
|
|
223
|
+
removeButtonAriaHidden: removeButton.getAttribute("aria-hidden"),
|
|
224
|
+
removeButtonDisabled: removeButton.disabled,
|
|
225
|
+
microBitUsesConnectControl: window.getComputedStyle(microBitAction).backgroundImage.includes(
|
|
226
|
+
"connect_btn-default.svg"
|
|
227
|
+
),
|
|
228
|
+
microBitActionPosition: window.getComputedStyle(microBitAction).position,
|
|
205
229
|
rightCategoryIds: Array.from(document.querySelectorAll("#selectorsright .category-selector-button")).map(
|
|
206
230
|
(button) => button.id
|
|
207
231
|
),
|
|
@@ -216,22 +240,109 @@ describe("Chromium 79 smoke test", () => {
|
|
|
216
240
|
});
|
|
217
241
|
|
|
218
242
|
expect(enabledState).toEqual({
|
|
219
|
-
addButtonDisplay: "
|
|
220
|
-
addButtonAriaHidden: "
|
|
221
|
-
addButtonDisabled:
|
|
243
|
+
addButtonDisplay: "none",
|
|
244
|
+
addButtonAriaHidden: "true",
|
|
245
|
+
addButtonDisabled: true,
|
|
222
246
|
microBitButtonDisplay: "flex",
|
|
223
247
|
microBitButtonAriaHidden: "false",
|
|
224
248
|
microBitButtonDisabled: false,
|
|
249
|
+
removeButtonDisplay: "flex",
|
|
250
|
+
removeButtonAriaHidden: "false",
|
|
251
|
+
removeButtonDisabled: false,
|
|
252
|
+
microBitUsesConnectControl: true,
|
|
253
|
+
microBitActionPosition: "static",
|
|
225
254
|
rightCategoryIds: ["cog-start", "cog-looks", "cog-sound", "microbit-start", "microbit-looks"],
|
|
226
255
|
selectedRightCategoryIds: ["microbit-start"],
|
|
227
256
|
paletteBlockTypes: [
|
|
228
257
|
"microbitbuttonpressed",
|
|
229
|
-
"microbitgesture",
|
|
230
258
|
"microbittilted",
|
|
231
259
|
],
|
|
232
260
|
extensionEnabled: true,
|
|
233
261
|
});
|
|
234
262
|
|
|
263
|
+
const microBitTiltState = await page.evaluate(() => {
|
|
264
|
+
const paletteBlock = Array.from(document.querySelectorAll("#palette > div"))
|
|
265
|
+
.find((block) => block.owner && block.owner.blocktype === "microbittilted").owner;
|
|
266
|
+
return {
|
|
267
|
+
defaultValue: paletteBlock.getArgValue(),
|
|
268
|
+
options: JSON.parse(paletteBlock.arg.list),
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
expect(microBitTiltState).toEqual({
|
|
273
|
+
defaultValue: "microbittiltright",
|
|
274
|
+
options: [
|
|
275
|
+
"microbittiltright",
|
|
276
|
+
"microbittiltleft",
|
|
277
|
+
"microbittiltbackward",
|
|
278
|
+
"microbittiltforward",
|
|
279
|
+
],
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const legacyMicroBitTiltState = await page.evaluate(() => {
|
|
283
|
+
const scripts = window.ScratchJr.getActiveScript().owner;
|
|
284
|
+
const block = scripts.insertKeyboardBlock(null, [[
|
|
285
|
+
"microbittilted",
|
|
286
|
+
"microbittiltany",
|
|
287
|
+
50,
|
|
288
|
+
50,
|
|
289
|
+
]]);
|
|
290
|
+
return {
|
|
291
|
+
value: block.getArgValue(),
|
|
292
|
+
icon: block.arg.icon,
|
|
293
|
+
options: JSON.parse(block.arg.list),
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
expect(legacyMicroBitTiltState).toEqual({
|
|
298
|
+
value: "microbittiltany",
|
|
299
|
+
icon: "microbittiltany",
|
|
300
|
+
options: [
|
|
301
|
+
"microbittiltright",
|
|
302
|
+
"microbittiltleft",
|
|
303
|
+
"microbittiltbackward",
|
|
304
|
+
"microbittiltforward",
|
|
305
|
+
],
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const standardPaletteUndoGap = await getPaletteUndoGap(page);
|
|
309
|
+
const maximumPaletteUndoGap = await page.evaluate(() => window.innerHeight * 0.02);
|
|
310
|
+
await page.setViewport({ width: 1200, height: 600 });
|
|
311
|
+
const widePaletteUndoGap = await getPaletteUndoGap(page);
|
|
312
|
+
await page.setViewport({ width: 800, height: 600 });
|
|
313
|
+
|
|
314
|
+
expect(standardPaletteUndoGap).toBeGreaterThanOrEqual(0);
|
|
315
|
+
expect(standardPaletteUndoGap).toBeLessThanOrEqual(maximumPaletteUndoGap);
|
|
316
|
+
expect(widePaletteUndoGap).toBeCloseTo(standardPaletteUndoGap, 1);
|
|
317
|
+
|
|
318
|
+
const connectedActionState = await page.evaluate(() => {
|
|
319
|
+
const microBitButton = document.getElementById("microBitConnectionButton");
|
|
320
|
+
const microBitAction = microBitButton.querySelector(".iconButtonContainer");
|
|
321
|
+
microBitButton.classList.add("connectButtonConnected");
|
|
322
|
+
microBitAction.classList.remove("notConnectedButtonContainer");
|
|
323
|
+
microBitAction.classList.add("connectedButtonContainer");
|
|
324
|
+
microBitAction.textContent = "DISCONNECT";
|
|
325
|
+
|
|
326
|
+
const actionStyle = window.getComputedStyle(microBitAction);
|
|
327
|
+
const result = {
|
|
328
|
+
text: microBitAction.textContent,
|
|
329
|
+
backgroundImage: actionStyle.backgroundImage,
|
|
330
|
+
position: actionStyle.position,
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
microBitButton.classList.remove("connectButtonConnected");
|
|
334
|
+
microBitAction.classList.remove("connectedButtonContainer");
|
|
335
|
+
microBitAction.classList.add("notConnectedButtonContainer");
|
|
336
|
+
microBitAction.textContent = "";
|
|
337
|
+
return result;
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
expect(connectedActionState).toEqual({
|
|
341
|
+
text: "DISCONNECT",
|
|
342
|
+
backgroundImage: "none",
|
|
343
|
+
position: "static",
|
|
344
|
+
});
|
|
345
|
+
|
|
235
346
|
await page.click("#microbit-looks");
|
|
236
347
|
await page.waitForFunction(
|
|
237
348
|
() => Array.from(document.querySelectorAll("#palette > div")).some(
|
|
@@ -285,8 +396,8 @@ describe("Chromium 79 smoke test", () => {
|
|
|
285
396
|
});
|
|
286
397
|
expect(blocksAfterInsert).toContain("microbitdisplayclear");
|
|
287
398
|
|
|
288
|
-
await
|
|
289
|
-
await page.waitForSelector("#
|
|
399
|
+
await page.click("#microBitRemoveButton");
|
|
400
|
+
await page.waitForSelector("#microBitExtensionRemoveWarning.show", { timeout: 30_000 });
|
|
290
401
|
const loadedLibraryState = await page.evaluate(() => ({
|
|
291
402
|
microBitCardAction: document.getElementById("microBitExtensionCardAction").textContent.trim(),
|
|
292
403
|
microBitCardLoaded: document.getElementById("microBitExtensionCard").classList.contains("loaded"),
|
|
@@ -296,8 +407,6 @@ describe("Chromium 79 smoke test", () => {
|
|
|
296
407
|
microBitCardLoaded: true,
|
|
297
408
|
});
|
|
298
409
|
|
|
299
|
-
await page.click("#microBitExtensionCard");
|
|
300
|
-
await page.waitForSelector("#microBitExtensionRemoveWarning.show", { timeout: 30_000 });
|
|
301
410
|
await page.click("#microBitExtensionRemoveCancel");
|
|
302
411
|
await page.waitForFunction(
|
|
303
412
|
() => !document.getElementById("microBitExtensionRemoveWarning").classList.contains("show"),
|
|
@@ -312,7 +421,12 @@ describe("Chromium 79 smoke test", () => {
|
|
|
312
421
|
hasMicroBitBlock: true,
|
|
313
422
|
});
|
|
314
423
|
|
|
315
|
-
await page.click("
|
|
424
|
+
await page.click(".extensionsLibraryClose");
|
|
425
|
+
await page.waitForFunction(
|
|
426
|
+
() => !document.getElementById("extensionsLibrary").classList.contains("in"),
|
|
427
|
+
{ timeout: 30_000 }
|
|
428
|
+
);
|
|
429
|
+
await page.click("#microBitRemoveButton");
|
|
316
430
|
await page.waitForSelector("#microBitExtensionRemoveWarning.show", { timeout: 30_000 });
|
|
317
431
|
await page.click("#microBitExtensionRemoveConfirm");
|
|
318
432
|
await page.waitForFunction(
|
|
@@ -324,6 +438,7 @@ describe("Chromium 79 smoke test", () => {
|
|
|
324
438
|
const unloadedState = await page.evaluate(() => ({
|
|
325
439
|
addButtonDisplay: window.getComputedStyle(document.getElementById("addExtensionButton")).display,
|
|
326
440
|
microBitButtonDisplay: window.getComputedStyle(document.getElementById("microBitConnectionButton")).display,
|
|
441
|
+
removeButtonDisplay: window.getComputedStyle(document.getElementById("microBitRemoveButton")).display,
|
|
327
442
|
extensionsLibraryOpen: document.getElementById("extensionsLibrary").classList.contains("in"),
|
|
328
443
|
microBitCardAction: document.getElementById("microBitExtensionCardAction").textContent.trim(),
|
|
329
444
|
microBitCardLoaded: document.getElementById("microBitExtensionCard").classList.contains("loaded"),
|
|
@@ -336,6 +451,7 @@ describe("Chromium 79 smoke test", () => {
|
|
|
336
451
|
expect(unloadedState).toEqual({
|
|
337
452
|
addButtonDisplay: "flex",
|
|
338
453
|
microBitButtonDisplay: "none",
|
|
454
|
+
removeButtonDisplay: "none",
|
|
339
455
|
extensionsLibraryOpen: false,
|
|
340
456
|
microBitCardAction: "+",
|
|
341
457
|
microBitCardLoaded: false,
|