@robotical/martyblocksjr 4.2.1 → 4.2.2
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/app.bundle.js +1 -1
- package/editions/free/src/assets/ui/viewOnCompactWideLabel.png +0 -0
- package/editions/free/src/css/editor.css +5 -0
- package/editions/free/src/css/editorleftpanel.css +8 -8
- package/package.json +1 -1
- package/tests/e2e/accessibility.e2e.test.js +1 -0
- package/tests/e2e/animated-sprite-paint-disabled.e2e.test.js +90 -2
- package/tests/e2e/marty-script-activation-paths.e2e.test.js +71 -0
|
Binary file
|
|
@@ -390,6 +390,11 @@ div.frame {
|
|
|
390
390
|
outline-offset: 4px;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
+
#blockspalette .categoryselector button[aria-pressed="true"]:focus,
|
|
394
|
+
#blockspalette .categoryselectorright button[aria-pressed="true"]:focus{
|
|
395
|
+
outline: none;
|
|
396
|
+
}
|
|
397
|
+
|
|
393
398
|
#blockspalette .categoryselectorright{
|
|
394
399
|
display: inline-block;
|
|
395
400
|
word-spacing: -1;
|
|
@@ -313,11 +313,11 @@
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
.marty-mode-card {
|
|
316
|
-
background: url('../assets/ui/
|
|
317
|
-
background-size: 100%;
|
|
316
|
+
background: url('../assets/ui/viewOnCompactWideLabel.png') no-repeat left top;
|
|
317
|
+
background-size: 100% 100%;
|
|
318
318
|
position: relative;
|
|
319
319
|
display: inline-block;
|
|
320
|
-
width: ${css_vh(
|
|
320
|
+
width: ${css_vh(23.18)};
|
|
321
321
|
height: ${css_vh(10.16)};
|
|
322
322
|
margin: 0px;
|
|
323
323
|
margin-bottom: ${css_vh(-0.39)};
|
|
@@ -346,7 +346,7 @@
|
|
|
346
346
|
position: absolute;
|
|
347
347
|
text-align: center;
|
|
348
348
|
top: ${css_vh(3.91)};
|
|
349
|
-
left: ${css_vh(
|
|
349
|
+
left: ${css_vh(9.24)};
|
|
350
350
|
margin: 0px;
|
|
351
351
|
padding: 0px;
|
|
352
352
|
line-height: ${css_vh(2.60)};
|
|
@@ -356,7 +356,7 @@
|
|
|
356
356
|
font-family: 'Lato Regular';
|
|
357
357
|
font-weight: bold;
|
|
358
358
|
font-size: ${css_vh(1.69)};
|
|
359
|
-
width: ${css_vh(
|
|
359
|
+
width: ${css_vh(11.97)};
|
|
360
360
|
cursor: default;
|
|
361
361
|
color: #F9A737;
|
|
362
362
|
}
|
|
@@ -493,9 +493,9 @@
|
|
|
493
493
|
position: absolute;
|
|
494
494
|
background: url('../assets/paint/paintbrush.svg');
|
|
495
495
|
background-size: 100% 100%;
|
|
496
|
-
width: ${css_vh(5.
|
|
497
|
-
height: ${css_vh(5.
|
|
498
|
-
top: ${css_vh(2.
|
|
496
|
+
width: ${css_vh(5.08)};
|
|
497
|
+
height: ${css_vh(5.08)};
|
|
498
|
+
top: ${css_vh(2.54)};
|
|
499
499
|
left: ${css_vh(17.45)};
|
|
500
500
|
margin: 0px;
|
|
501
501
|
padding: 0px;
|
package/package.json
CHANGED
|
@@ -378,6 +378,7 @@ describe('Accessibility shell audit', () => {
|
|
|
378
378
|
const motionButton = document.getElementById('sprite-motion');
|
|
379
379
|
return motionButton && motionButton.getAttribute('aria-pressed') === 'true';
|
|
380
380
|
}, { timeout: 5_000 });
|
|
381
|
+
expect((await getFocusStyles(page, '#sprite-motion')).outlineStyle).toBe('none');
|
|
381
382
|
await page.waitForSelector('#forward_block[role="button"]', { timeout: 30_000 });
|
|
382
383
|
|
|
383
384
|
await expectNamedControls(page, ['#forward_block', '#back_block']);
|
|
@@ -72,7 +72,94 @@ async function openEditor() {
|
|
|
72
72
|
return { browser, page, errors };
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
async function dragBlockToScripts(page, categorySelector, blockSelector, blockType) {
|
|
76
|
+
const blockCount = await page.evaluate(() => window.ScratchJr.getBlocks().length);
|
|
77
|
+
await page.click(categorySelector);
|
|
78
|
+
await page.waitForSelector(blockSelector, { visible: true });
|
|
79
|
+
|
|
80
|
+
const source = await page.$eval(blockSelector, (node) => {
|
|
81
|
+
const rect = node.getBoundingClientRect();
|
|
82
|
+
return {
|
|
83
|
+
x: rect.left + rect.width / 2,
|
|
84
|
+
y: rect.top + rect.height / 2,
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
const target = await page.$eval("#scripts", (node) => {
|
|
88
|
+
const rect = node.getBoundingClientRect();
|
|
89
|
+
return {
|
|
90
|
+
x: rect.left + Math.min(220, rect.width / 2),
|
|
91
|
+
y: rect.top + Math.min(170, rect.height / 2),
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await page.mouse.move(source.x, source.y);
|
|
96
|
+
await page.mouse.down();
|
|
97
|
+
await page.mouse.move(target.x, target.y, { steps: 12 });
|
|
98
|
+
await page.mouse.up();
|
|
99
|
+
|
|
100
|
+
await page.waitForFunction(
|
|
101
|
+
(before, type) => window.ScratchJr.getBlocks().length > before
|
|
102
|
+
&& window.ScratchJr.getBlocks().some((block) => block.blocktype === type),
|
|
103
|
+
{ timeout: 30_000 },
|
|
104
|
+
blockCount,
|
|
105
|
+
blockType
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function getSelectedSpritePaintState(page) {
|
|
110
|
+
return page.evaluate(() => {
|
|
111
|
+
const sprite = window.ScratchJr && window.ScratchJr.getSprite();
|
|
112
|
+
const thumb = sprite && sprite.thumbnail;
|
|
113
|
+
const brush = thumb && thumb.querySelector(".brush");
|
|
114
|
+
if (!sprite || !thumb || !brush) {
|
|
115
|
+
throw new Error("Selected sprite paint controls were not found");
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
md5: sprite.md5,
|
|
119
|
+
thumbClass: thumb.className,
|
|
120
|
+
brushDisplay: window.getComputedStyle(brush).display,
|
|
121
|
+
blockTypes: window.ScratchJr.getBlocks().map((block) => block.blocktype),
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
describe("sprite paint editing availability", () => {
|
|
127
|
+
it(
|
|
128
|
+
"keeps Marty paint editing disabled after dropping a block",
|
|
129
|
+
async () => {
|
|
130
|
+
const { browser, page, errors } = await openEditor();
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const beforeDrop = await getSelectedSpritePaintState(page);
|
|
134
|
+
expect(beforeDrop.md5).toBe("Sprites_Marty.svg");
|
|
135
|
+
expect(beforeDrop.thumbClass).toContain("martynoneditable");
|
|
136
|
+
expect(beforeDrop.brushDisplay).toBe("none");
|
|
137
|
+
|
|
138
|
+
await dragBlockToScripts(page, "#sprite-motion", "#forward_block", "forward");
|
|
139
|
+
|
|
140
|
+
const afterDrop = await getSelectedSpritePaintState(page);
|
|
141
|
+
expect(afterDrop.thumbClass).toContain("martynoneditable");
|
|
142
|
+
expect(afterDrop.brushDisplay).toBe("none");
|
|
143
|
+
expect(afterDrop.blockTypes).toContain("forward");
|
|
144
|
+
|
|
145
|
+
const paintFrameVisible = await page.evaluate(() => {
|
|
146
|
+
const brush = window.ScratchJr.getSprite().thumbnail.querySelector(".brush");
|
|
147
|
+
brush.dispatchEvent(new PointerEvent("pointerdown", {
|
|
148
|
+
bubbles: true,
|
|
149
|
+
cancelable: true,
|
|
150
|
+
pointerType: "mouse",
|
|
151
|
+
}));
|
|
152
|
+
return window.getComputedStyle(document.getElementById("paintframe")).display !== "none";
|
|
153
|
+
});
|
|
154
|
+
expect(paintFrameVisible).toBe(false);
|
|
155
|
+
expect(errors).toEqual([]);
|
|
156
|
+
} finally {
|
|
157
|
+
await browser.close();
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
60_000
|
|
161
|
+
);
|
|
162
|
+
|
|
76
163
|
it(
|
|
77
164
|
"disables paint editing for the animated bee in the library and sprite panel",
|
|
78
165
|
async () => {
|
|
@@ -231,7 +318,8 @@ describe("animated sprite paint editing", () => {
|
|
|
231
318
|
expect(layoutState.selectedBackgroundSize).toBe("100% 100%");
|
|
232
319
|
expect(layoutState.name.right).toBeLessThanOrEqual(layoutState.brush.left + 0.5);
|
|
233
320
|
expect(layoutState.brush.left).toBeGreaterThanOrEqual(layoutState.selected.left);
|
|
234
|
-
expect(layoutState.
|
|
321
|
+
expect(layoutState.selected.right - layoutState.brush.right)
|
|
322
|
+
.toBeGreaterThanOrEqual(layoutState.brush.width * 0.1);
|
|
235
323
|
expect(layoutState.brush.top).toBeGreaterThanOrEqual(layoutState.selected.top);
|
|
236
324
|
expect(layoutState.brush.bottom).toBeLessThanOrEqual(layoutState.selected.bottom);
|
|
237
325
|
|
|
@@ -249,6 +249,77 @@ describe("Marty script activation paths", () => {
|
|
|
249
249
|
}
|
|
250
250
|
});
|
|
251
251
|
|
|
252
|
+
it("keeps the Marty mode sidebar card and full label stable after block drops", async () => {
|
|
253
|
+
const { browser, page, errors } = await openPage("/editor.html?mode=edit");
|
|
254
|
+
try {
|
|
255
|
+
await waitForEditorReady(page);
|
|
256
|
+
const spriteCardLayout = await page.evaluate(() => {
|
|
257
|
+
const card = document.querySelector("#spritecc .spritethumb[aria-pressed=\"true\"]");
|
|
258
|
+
const label = card && card.querySelector(".sname");
|
|
259
|
+
if (!card || !label) {
|
|
260
|
+
throw new Error("Selected sprite card layout was not found");
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
cardWidth: card.getBoundingClientRect().width,
|
|
264
|
+
labelWidth: label.getBoundingClientRect().width
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
await setMartyMode(page, true);
|
|
269
|
+
const getMartyCardLayout = () => page.evaluate(() => {
|
|
270
|
+
const card = document.getElementById("martyModeSidebarCard");
|
|
271
|
+
const label = card && card.querySelector(".marty-mode-card-label");
|
|
272
|
+
if (!card || !label) {
|
|
273
|
+
throw new Error("Marty mode sidebar card layout was not found");
|
|
274
|
+
}
|
|
275
|
+
const cardStyle = window.getComputedStyle(card);
|
|
276
|
+
const labelStyle = window.getComputedStyle(label);
|
|
277
|
+
const cardRect = card.getBoundingClientRect();
|
|
278
|
+
const labelRect = label.getBoundingClientRect();
|
|
279
|
+
return {
|
|
280
|
+
className: card.className,
|
|
281
|
+
cardWidth: cardRect.width,
|
|
282
|
+
cardLeft: cardRect.left,
|
|
283
|
+
cardRight: cardRect.right,
|
|
284
|
+
labelText: label.textContent,
|
|
285
|
+
labelWidth: labelRect.width,
|
|
286
|
+
labelLeft: labelRect.left,
|
|
287
|
+
labelRight: labelRect.right,
|
|
288
|
+
labelClientWidth: label.clientWidth,
|
|
289
|
+
labelScrollWidth: label.scrollWidth,
|
|
290
|
+
hasBrush: Boolean(card.querySelector(".brush")),
|
|
291
|
+
backgroundImage: cardStyle.backgroundImage,
|
|
292
|
+
backgroundSize: cardStyle.backgroundSize,
|
|
293
|
+
overflow: labelStyle.overflow,
|
|
294
|
+
textOverflow: labelStyle.textOverflow,
|
|
295
|
+
whiteSpace: labelStyle.whiteSpace
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
const martyCardLayout = await getMartyCardLayout();
|
|
299
|
+
|
|
300
|
+
expect(martyCardLayout.cardWidth).toBeCloseTo(spriteCardLayout.cardWidth, 1);
|
|
301
|
+
expect(martyCardLayout.labelWidth).toBeGreaterThan(spriteCardLayout.labelWidth);
|
|
302
|
+
expect(martyCardLayout.labelLeft).toBeGreaterThanOrEqual(martyCardLayout.cardLeft);
|
|
303
|
+
expect(martyCardLayout.labelRight).toBeLessThanOrEqual(martyCardLayout.cardRight);
|
|
304
|
+
expect(martyCardLayout.labelText).toBe("Marty Mode");
|
|
305
|
+
expect(martyCardLayout.hasBrush).toBe(false);
|
|
306
|
+
expect(martyCardLayout.backgroundImage).toContain("viewOnCompactWideLabel.png");
|
|
307
|
+
expect(martyCardLayout.backgroundSize).toBe("100% 100%");
|
|
308
|
+
expect(martyCardLayout).toMatchObject({
|
|
309
|
+
overflow: "hidden",
|
|
310
|
+
textOverflow: "ellipsis",
|
|
311
|
+
whiteSpace: "nowrap"
|
|
312
|
+
});
|
|
313
|
+
expect(martyCardLayout.labelScrollWidth).toBeLessThanOrEqual(martyCardLayout.labelClientWidth);
|
|
314
|
+
|
|
315
|
+
await dragMartyBlock(page);
|
|
316
|
+
expect(await getMartyCardLayout()).toEqual(martyCardLayout);
|
|
317
|
+
expect(errors).toEqual([]);
|
|
318
|
+
} finally {
|
|
319
|
+
await browser.close();
|
|
320
|
+
}
|
|
321
|
+
}, 60000);
|
|
322
|
+
|
|
252
323
|
it("activates the script after duplicating a page in Marty mode", async () => {
|
|
253
324
|
const { browser, page, errors } = await openPage("/editor.html?mode=edit");
|
|
254
325
|
try {
|