Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
288 commits
Select commit Hold shift + click to select a range
6c6b43d
NavBanner: Remove default export
bennorth Dec 31, 2025
9ff1d2d
InertNavBanner: Define component
bennorth Dec 31, 2025
27188aa
(Remove unnecessary braces)
bennorth Dec 31, 2025
f6ae4ed
fetchTutorialResourceOrThrow(): Define helper
bennorth Dec 23, 2025
6677336
tutorialResourceText(): Throw on fetch failure
bennorth Dec 23, 2025
308d062
tutorialResourceParsedJson(): Throw on failure
bennorth Dec 23, 2025
8ee7032
(Reformat)
bennorth Dec 29, 2025
94c3f3e
createProjectFromTutorial(): Take navigateOptions
bennorth Dec 29, 2025
63e4d5e
CreateProjectFromTutorialArgs: Define type
bennorth Dec 23, 2025
ffed2ef
createProjectFromTutorial(): Take richer args
bennorth Dec 19, 2025
320cc70
createProjectFromTutorial(): Update caller
bennorth Dec 19, 2025
826bf4a
Validate args for "flat" tutorials
bennorth Dec 19, 2025
3df9462
createProjectFromTutorial(): Heed nav/replace arg
bennorth Dec 29, 2025
b93e264
JrTutorialCheckpointSkeleton: Define type
bennorth Dec 19, 2025
13909ce
jrTutorialCheckpointCreateOptions(): Define
bennorth Dec 19, 2025
d67836d
Create jr-tut-following project at checkpoint
bennorth Dec 19, 2025
a80891c
(Tidy up imports)
bennorth Dec 23, 2025
baacc5c
StartTutorialAtCheckpointRunArgs: Define type
bennorth Dec 23, 2025
2d69055
ValidatedRunArgs: Define type
bennorth Dec 23, 2025
c8d6204
StartTutorialAtCheckpointRunState: Define type
bennorth Dec 23, 2025
03b1015
StartTutorialAtCheckpointFlow: Define type
bennorth Dec 23, 2025
fd5de48
validatedArgs(): Define helper
bennorth Dec 23, 2025
1616be7
prepare(): Define
bennorth Dec 23, 2025
1e038fd
attempt(): Define
bennorth Dec 23, 2025
bf1064d
startTutorialAtCheckpointFlow: Define
bennorth Dec 23, 2025
5d8ea05
StartTutorialAtCheckpointFlow: Include in model
bennorth Dec 23, 2025
447ae69
Content: Define local component
bennorth Dec 23, 2025
1497f2a
StartTutorialAtCheckpoint: Define component
bennorth Dec 23, 2025
7b187e1
Style exception display within start-tut-at-chap
bennorth Dec 23, 2025
5ab4ef7
Route to StartTutorialAtCheckpoint
bennorth Dec 22, 2025
cd4e25d
assertJrTutChapterNumber(): Extract helper
bennorth Dec 31, 2025
0a9e0a3
Simplify "Navigation of per-method lesson" tests
bennorth Dec 31, 2025
487fccf
assertOnFrontPage(): Define e2e helper
bennorth Dec 31, 2025
1120ae4
(Add comment)
bennorth Dec 31, 2025
c207861
Add "Start jr tutorial at chapter" e2e skeleton
bennorth Dec 31, 2025
a00b737
Add classes for use in e2e tests
bennorth Dec 31, 2025
7b38289
assertTutorialNameIncludes(): Define helper
bennorth Dec 31, 2025
413f2a5
assertChapterStartContent(): Define helper
bennorth Dec 31, 2025
5c99b5f
attemptCreateProject(): Define helper
bennorth Dec 31, 2025
8bf8af6
assertError(): Define helper
bennorth Dec 31, 2025
a058e19
Add "start tutorial at specified chapter" test
bennorth Dec 31, 2025
a0a00df
Add "reject invalid tutorial slug" test
bennorth Dec 31, 2025
3b4d49a
Add "reject invalid chapter index…" test
bennorth Dec 31, 2025
a8ff456
Add "navigate with replacement" test
bennorth Dec 31, 2025
7ef7284
Update e2e tests re solid-white image in media lib
bennorth Dec 31, 2025
b3b8d52
Pull set-up out into beforeEach()
bennorth Dec 31, 2025
b6801cd
launchNthTutorial(): Define helper
bennorth Dec 31, 2025
deb48f9
Add "can start tutorials" test
bennorth Dec 31, 2025
9c3cdd1
ErrorMessageDisplay: Define component
bennorth Jan 1, 2026
321d86c
ExceptionDisplay: Simplify
bennorth Jan 1, 2026
0ce1f70
GenericErrorModal: Simplify
bennorth Jan 1, 2026
750978f
Style technical details content
bennorth Jan 1, 2026
4c548fb
(Allow larger bundle size without warning)
bennorth Jan 1, 2026
698fbf8
jrTut/CheckptCreateOpts(): Demo if "one past end"
bennorth Jan 1, 2026
9f23a88
(Tidy up imports)
bennorth Jan 6, 2026
71912d0
Add docstring
bennorth Jan 1, 2026
ae841cf
createDemoFromTutorial(): Simplify
bennorth Jan 1, 2026
243b73d
Improve loading spinner's style for keynav-help
bennorth Jan 1, 2026
0643353
Improve styling of activity-tab icons
bennorth Jan 1, 2026
87c1c2e
Fix dev-mode keynav bug
bennorth Jan 1, 2026
23cfbec
Add global-focus-steering class (existing content)
bennorth Jan 1, 2026
85066f3
SpecimenInformation: Include in tab order
bennorth Jan 1, 2026
1e553a8
Make "g h" focus (as fallback) gfs__help-content
bennorth Jan 1, 2026
1454e11
Mark key-nav help as gfs__help-content
bennorth Jan 1, 2026
d5ed25f
(Extract local variable)
bennorth Jan 1, 2026
a3b8ccc
Support "g h" in flat IDE
bennorth Jan 1, 2026
a09481b
Add v4 flat zipfile fixture
bennorth Jan 1, 2026
781e527
make_content_v4_flat(): Define helper
bennorth Jan 1, 2026
64cf574
Add "v4-flat-linked-to-specimen" zipfile
bennorth Jan 1, 2026
3c5d2e2
assertFocus(): Handle some new areas
bennorth Jan 1, 2026
76cde3d
Add "Global focus steering" e2e skeleton
bennorth Jan 1, 2026
8f99e70
invokeFocusShortcut(): Define helper
bennorth Jan 1, 2026
076ad9f
Add "flat IDE" context skeleton
bennorth Jan 1, 2026
cfd8ddb
Add "specimen link" (flat) test
bennorth Jan 1, 2026
905c856
Add "tutorial link" (flat) test
bennorth Jan 1, 2026
3985f85
Add "per-method IDE" context skeleton
bennorth Jan 1, 2026
d0d9484
Add "specimen link" (per-method) test
bennorth Jan 1, 2026
b63362a
Add "multiple costumes" (per-method) test
bennorth Jan 1, 2026
5d48339
Add "tutorial link" (per-method) test
bennorth Jan 1, 2026
33f725f
Add apologetic comment
bennorth Jan 1, 2026
420f1b5
InertNavBanner: Add (true) link to app home
bennorth Jan 6, 2026
3dccef1
(Update docstring)
bennorth Jan 6, 2026
0d89bf2
(Reformat)
bennorth Jan 6, 2026
e3ae70f
Add "navigate home outside router" test
bennorth Jan 6, 2026
cc692ca
Fetch project-descriptor earlier when loading
bennorth Jan 6, 2026
5173a2c
L/ContentLoadTaskDescriptor: Add program-kind slot
bennorth Jan 6, 2026
5c1d1be
Provide projectProgramKind slot value
bennorth Jan 6, 2026
7e6769d
Add programKind param to deref functions
bennorth Jan 6, 2026
e2c5ddc
Provide programKind arg to deref functions
bennorth Jan 6, 2026
b9e3d88
Reject mismatched linked jr-tutorial content
bennorth Jan 6, 2026
2191b79
Reject mismatched linked specimen content
bennorth Jan 6, 2026
4d7c116
ErrorMessageDisplay: Add icon
bennorth Jan 6, 2026
21e05d0
(Reformat)
bennorth Jan 6, 2026
acac872
LinkedContentLoadingState: Enrich "failed" state
bennorth Jan 6, 2026
6bead30
Provide extra "failed" info
bennorth Jan 6, 2026
2ce95ea
L/Cont/LoadingStateSummary: Enrich "failed" state
bennorth Jan 6, 2026
a7bbf93
useHasLinkedContentOfKind(): Include "failed"
bennorth Jan 6, 2026
5dec456
MaybeContent: Show error if "failed"
bennorth Jan 6, 2026
7579d63
(Remove unnecessary console.log()s)
bennorth Jan 6, 2026
6069e98
assertShowsLinkedContentError(): Define helper
bennorth Jan 6, 2026
9262f1e
Add "rejects wrong program-kind" e2e skeleton
bennorth Jan 6, 2026
552ec34
Add per-method/flat specimen mismatch tests
bennorth Jan 6, 2026
eb2b369
Add "v4-flat-linked-to-jr-tutorial" zipfile
bennorth Jan 6, 2026
07e6a68
Add "rejects wrong program-kind" test re jr lesson
bennorth Jan 6, 2026
2a0694e
ItShowsToastForDescr: Add assertCompletion slot
bennorth Jan 6, 2026
c776a3a
itShowsToastFor(): Assert completion if req
bennorth Jan 6, 2026
0563ee3
Assert "sbs rename asset" completion (toast e2e)
bennorth Jan 6, 2026
a0fa7bb
rounded corners of code editor in flat projects
MartinNang Jan 8, 2026
fe19aee
Revert "remove resizable panels"
MartinNang Jan 8, 2026
8dfc887
Collapse/expand info panel when resizing
MartinNang Jan 8, 2026
5ba9c4f
removed outline on separator elements (not needed since the backgroun…
MartinNang Jan 8, 2026
6708218
Unit tests: Remove assignment to globalThis.crypto
bennorth Nov 28, 2025
69299fc
Add asset with uppercase filename
bennorth Dec 5, 2025
5e1582a
Add project containing uppercase-named asset
bennorth Dec 5, 2025
32355d2
Add failing "zipfile uppercase asset f/name" test
bennorth Dec 5, 2025
3372015
typeFromExtension(): Update generator; regenerate
bennorth Dec 5, 2025
412a295
Add "asset with uppercase filename" test
bennorth Dec 5, 2025
c27f8fb
(Reformat)
bennorth Dec 15, 2025
760f667
Update e2e test
bennorth Dec 15, 2025
4a6b30e
Add class to "home" logo link (needed by e2e test)
bennorth Dec 15, 2025
90a53bc
Add "arrow-up-right-from-square" FA icon
bennorth Dec 16, 2025
6cc18fd
ExternalLinkIndicator: Define component
bennorth Dec 16, 2025
c669f02
NavBanner: Use ExternalLinkIndicator
bennorth Dec 16, 2025
39a5f96
Rename file to "decorations"
bennorth Dec 16, 2025
b1a27a6
Widen activity bar
bennorth Dec 16, 2025
42149bd
projectCreationArgs(): Simplify signature
bennorth Dec 19, 2025
a4926a1
ITutorialCollection: Define, use slice-types
bennorth Dec 19, 2025
990706c
(Add braces)
bennorth Dec 19, 2025
f3b393c
(Tighten type)
bennorth Dec 19, 2025
4427760
(Remove stray space)
bennorth Dec 22, 2025
b1f335d
TutorialSummaryDisplay: Remove stale code
bennorth Dec 22, 2025
f70a014
Update eslint packages
bennorth Dec 23, 2025
47359bd
ExceptionDisplayProps: Define type
bennorth Dec 23, 2025
635cc90
ExceptionDisplay: Accept props of broader type
bennorth Dec 23, 2025
bb44382
(Tidy up imports; reformat)
bennorth Dec 23, 2025
e85ec0b
DemoFromZipfileURLState: Simplify definition
bennorth Dec 22, 2025
5405f84
Note error-handling query
bennorth Dec 22, 2025
f3e0356
NavBanner: Remove default export
bennorth Dec 31, 2025
8be02c0
InertNavBanner: Define component
bennorth Dec 31, 2025
b20a520
(Remove unnecessary braces)
bennorth Dec 31, 2025
7e99a8a
fetchTutorialResourceOrThrow(): Define helper
bennorth Dec 23, 2025
7b53678
tutorialResourceText(): Throw on fetch failure
bennorth Dec 23, 2025
32083c5
tutorialResourceParsedJson(): Throw on failure
bennorth Dec 23, 2025
8171266
(Reformat)
bennorth Dec 29, 2025
d71b8df
createProjectFromTutorial(): Take navigateOptions
bennorth Dec 29, 2025
a1eb736
CreateProjectFromTutorialArgs: Define type
bennorth Dec 23, 2025
459d7b7
createProjectFromTutorial(): Take richer args
bennorth Dec 19, 2025
c0d1d39
createProjectFromTutorial(): Update caller
bennorth Dec 19, 2025
27aeab9
Validate args for "flat" tutorials
bennorth Dec 19, 2025
c3edb66
createProjectFromTutorial(): Heed nav/replace arg
bennorth Dec 29, 2025
f795156
JrTutorialCheckpointSkeleton: Define type
bennorth Dec 19, 2025
9e21858
jrTutorialCheckpointCreateOptions(): Define
bennorth Dec 19, 2025
1e4c1b2
Create jr-tut-following project at checkpoint
bennorth Dec 19, 2025
c7877e8
(Tidy up imports)
bennorth Dec 23, 2025
64e52e7
StartTutorialAtCheckpointRunArgs: Define type
bennorth Dec 23, 2025
45fca0b
ValidatedRunArgs: Define type
bennorth Dec 23, 2025
22533bf
StartTutorialAtCheckpointRunState: Define type
bennorth Dec 23, 2025
d44c496
StartTutorialAtCheckpointFlow: Define type
bennorth Dec 23, 2025
e43e760
validatedArgs(): Define helper
bennorth Dec 23, 2025
6df76eb
prepare(): Define
bennorth Dec 23, 2025
fa473bc
attempt(): Define
bennorth Dec 23, 2025
18fac17
startTutorialAtCheckpointFlow: Define
bennorth Dec 23, 2025
b70b36f
StartTutorialAtCheckpointFlow: Include in model
bennorth Dec 23, 2025
66c2c6c
Content: Define local component
bennorth Dec 23, 2025
8ce55bd
StartTutorialAtCheckpoint: Define component
bennorth Dec 23, 2025
cdcd85b
Style exception display within start-tut-at-chap
bennorth Dec 23, 2025
4b70119
Route to StartTutorialAtCheckpoint
bennorth Dec 22, 2025
c99ce8b
assertJrTutChapterNumber(): Extract helper
bennorth Dec 31, 2025
afba88e
Simplify "Navigation of per-method lesson" tests
bennorth Dec 31, 2025
1adbbcc
assertOnFrontPage(): Define e2e helper
bennorth Dec 31, 2025
cf395a4
(Add comment)
bennorth Dec 31, 2025
c50b4c2
Add "Start jr tutorial at chapter" e2e skeleton
bennorth Dec 31, 2025
c5323d1
Add classes for use in e2e tests
bennorth Dec 31, 2025
2c05ac4
assertTutorialNameIncludes(): Define helper
bennorth Dec 31, 2025
b92bd74
assertChapterStartContent(): Define helper
bennorth Dec 31, 2025
dbd42ef
attemptCreateProject(): Define helper
bennorth Dec 31, 2025
c419c84
assertError(): Define helper
bennorth Dec 31, 2025
001f1dd
Add "start tutorial at specified chapter" test
bennorth Dec 31, 2025
ab96988
Add "reject invalid tutorial slug" test
bennorth Dec 31, 2025
20316ab
Add "reject invalid chapter index…" test
bennorth Dec 31, 2025
7074f87
Add "navigate with replacement" test
bennorth Dec 31, 2025
4f39c1e
Update e2e tests re solid-white image in media lib
bennorth Dec 31, 2025
9402e29
Pull set-up out into beforeEach()
bennorth Dec 31, 2025
2a19808
launchNthTutorial(): Define helper
bennorth Dec 31, 2025
a98ae3d
Add "can start tutorials" test
bennorth Dec 31, 2025
50cb728
ErrorMessageDisplay: Define component
bennorth Jan 1, 2026
3eb51e2
ExceptionDisplay: Simplify
bennorth Jan 1, 2026
2fd57e5
GenericErrorModal: Simplify
bennorth Jan 1, 2026
19740b1
Style technical details content
bennorth Jan 1, 2026
dc8b622
(Allow larger bundle size without warning)
bennorth Jan 1, 2026
8adc64b
jrTut/CheckptCreateOpts(): Demo if "one past end"
bennorth Jan 1, 2026
a7e1101
(Tidy up imports)
bennorth Jan 6, 2026
e7166e5
Add docstring
bennorth Jan 1, 2026
92c2aff
createDemoFromTutorial(): Simplify
bennorth Jan 1, 2026
a04889e
Improve loading spinner's style for keynav-help
bennorth Jan 1, 2026
96af12b
Improve styling of activity-tab icons
bennorth Jan 1, 2026
14dac74
Fix dev-mode keynav bug
bennorth Jan 1, 2026
747345a
Add global-focus-steering class (existing content)
bennorth Jan 1, 2026
d872357
SpecimenInformation: Include in tab order
bennorth Jan 1, 2026
003da7c
Make "g h" focus (as fallback) gfs__help-content
bennorth Jan 1, 2026
45e12d3
Mark key-nav help as gfs__help-content
bennorth Jan 1, 2026
105a7b7
(Extract local variable)
bennorth Jan 1, 2026
ec2ddfc
Support "g h" in flat IDE
bennorth Jan 1, 2026
9b3583a
Add v4 flat zipfile fixture
bennorth Jan 1, 2026
baa1c10
make_content_v4_flat(): Define helper
bennorth Jan 1, 2026
da9d677
Add "v4-flat-linked-to-specimen" zipfile
bennorth Jan 1, 2026
53d5ae8
assertFocus(): Handle some new areas
bennorth Jan 1, 2026
30109ae
Add "Global focus steering" e2e skeleton
bennorth Jan 1, 2026
3c20cdd
invokeFocusShortcut(): Define helper
bennorth Jan 1, 2026
e3ac7e3
Add "flat IDE" context skeleton
bennorth Jan 1, 2026
0c49721
Add "specimen link" (flat) test
bennorth Jan 1, 2026
060159f
Add "tutorial link" (flat) test
bennorth Jan 1, 2026
45744f1
Add "per-method IDE" context skeleton
bennorth Jan 1, 2026
2dda222
Add "specimen link" (per-method) test
bennorth Jan 1, 2026
985aef8
Add "multiple costumes" (per-method) test
bennorth Jan 1, 2026
e89da16
Add "tutorial link" (per-method) test
bennorth Jan 1, 2026
df2d5cf
Add apologetic comment
bennorth Jan 1, 2026
bce7ac7
InertNavBanner: Add (true) link to app home
bennorth Jan 6, 2026
ea0d442
(Update docstring)
bennorth Jan 6, 2026
2dfd595
(Reformat)
bennorth Jan 6, 2026
1175899
Add "navigate home outside router" test
bennorth Jan 6, 2026
ca5c04e
Fetch project-descriptor earlier when loading
bennorth Jan 6, 2026
5a333af
L/ContentLoadTaskDescriptor: Add program-kind slot
bennorth Jan 6, 2026
8059ee3
Provide projectProgramKind slot value
bennorth Jan 6, 2026
2816bdf
Add programKind param to deref functions
bennorth Jan 6, 2026
e86dd29
Provide programKind arg to deref functions
bennorth Jan 6, 2026
4dc36eb
Reject mismatched linked jr-tutorial content
bennorth Jan 6, 2026
26b0800
Reject mismatched linked specimen content
bennorth Jan 6, 2026
a069092
ErrorMessageDisplay: Add icon
bennorth Jan 6, 2026
4fca657
(Reformat)
bennorth Jan 6, 2026
711889c
LinkedContentLoadingState: Enrich "failed" state
bennorth Jan 6, 2026
2d4f470
Provide extra "failed" info
bennorth Jan 6, 2026
c4b118a
L/Cont/LoadingStateSummary: Enrich "failed" state
bennorth Jan 6, 2026
540fca6
useHasLinkedContentOfKind(): Include "failed"
bennorth Jan 6, 2026
2d50dae
MaybeContent: Show error if "failed"
bennorth Jan 6, 2026
46f954e
(Remove unnecessary console.log()s)
bennorth Jan 6, 2026
5cf763b
assertShowsLinkedContentError(): Define helper
bennorth Jan 6, 2026
6b5f14d
Add "rejects wrong program-kind" e2e skeleton
bennorth Jan 6, 2026
9a1a3fe
Add per-method/flat specimen mismatch tests
bennorth Jan 6, 2026
c581d1f
Add "v4-flat-linked-to-jr-tutorial" zipfile
bennorth Jan 6, 2026
bd0ded5
Add "rejects wrong program-kind" test re jr lesson
bennorth Jan 6, 2026
8dfe600
ItShowsToastForDescr: Add assertCompletion slot
bennorth Jan 6, 2026
6a4465d
itShowsToastFor(): Assert completion if req
bennorth Jan 6, 2026
c602a47
Assert "sbs rename asset" completion (toast e2e)
bennorth Jan 6, 2026
77c7191
Updated stage controls and panel styling, made buttons stick to botto…
MartinNang Dec 23, 2025
d52a688
removed ellipsis from dropdown menu and updated padding
MartinNang Jan 5, 2026
1a1a787
resize webapp if virtual/touchscreen keyboard is active
MartinNang Jan 7, 2026
b73491d
added box-shadows to panels and stage controls (wip)
MartinNang Jan 23, 2026
ae5c31c
Merge branch 'IDE_style_updates_clean' into resizable_panels
MartinNang Jan 23, 2026
c47b17c
squash! added box-shadows to panels and stage controls (wip)
MartinNang Jan 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions cypress/e2e/demos-of-tutorials.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ context("Demos of all tutorials", () => {
cy.get("ul.tutorial-list li").should("have.length", kExpNTutorials);
}

beforeEach(() => {
cy.pytchResetDatabase({ initialUrl: "/tutorials/" });
assertNTutorials();
});

function launchNthTutorial(tutorialIndex: number) {
const childNumber = tutorialIndex + 1;
cy.get(
`ul.tutorial-list li:nth-child(${childNumber})` +
' button[title="Learn how to make this project"]'
).click();
}

function launchNthTutorialDemo(tutorialIndex: number) {
const childNumber = tutorialIndex + 1;
cy.get(
Expand All @@ -13,10 +26,16 @@ context("Demos of all tutorials", () => {
).click();
}

it("can run demos", () => {
cy.pytchResetDatabase({ initialUrl: "/tutorials/" });
assertNTutorials();
it("can start tutorials", () => {
for (let tutIdx = 0; tutIdx !== kExpNTutorials; ++tutIdx) {
launchNthTutorial(tutIdx);
cy.get(".ActivityContent .ProgressTrail").should("be.visible");
cy.pytchHomeFromIDE();
cy.get(".NavBar li").contains("Tutorials").click();
}
});

it("can run demos", () => {
for (let tutIdx = 0; tutIdx !== kExpNTutorials; ++tutIdx) {
launchNthTutorialDemo(tutIdx);
cy.contains("Click the green flag to run");
Expand Down
9 changes: 9 additions & 0 deletions cypress/e2e/junior/actor-assets.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ context("Working with assets of an actor", () => {
assertCostumeNames(allCostumes);
});

it("asset with uppercase filename", () => {
const assetFilename = "RECTANGLE-RED-80-60.PNG";

selectSprite("Snake");
selectActorAspect("Costumes");
addFromFixture(assetFilename);
assertCostumeNames(["python-logo.png", assetFilename]);
});

it("has useful UI text for uploading", () => {
const assertContentCorrect = (headerMatch: string, bodyMatch: string) => {
launchAdd.assetFromThisDevice();
Expand Down
51 changes: 30 additions & 21 deletions cypress/e2e/junior/lesson.cy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { DiffViewKind, PrettyPrintedLine } from "../../../src/model/code-diff";
import { LinkedJrTutorialRef } from "../../../src/model/junior/jr-tutorial";
import { assertInIDE, withDownloadedZipfile } from "../utils";
import {
assertInIDE,
assertShowsLinkedContentError,
withDownloadedZipfile,
} from "../utils";
import {
assertActorNames,
assertJrTutChapterNumber,
assertTwoStateSwitchState,
clickUniqueSelected,
getActivityBarTab,
Expand Down Expand Up @@ -73,30 +78,17 @@ context("Navigation of per-method lesson", () => {
).click();
}

function assertChapterNumber(expNumber: number) {
if (expNumber === 0) {
cy.get(".chapter-title").should("be.visible");
cy.get(".chapter-title .chapter-number").should("not.exist");
return;
}

cy.get(".chapter-title .chapter-number").should(
"have.text",
`${expNumber} —`
);
}

it("can move through chapters", () => {
for (let i = 0; i !== 5; ++i) {
advanceToNextChapter(i);
const expChapter = i + 1;
assertChapterNumber(expChapter);
assertJrTutChapterNumber(expChapter);
}

// Jump directly back one at a time until chapter 1.
for (let i = 4; i !== 0; --i) {
jumpToChapter(i);
assertChapterNumber(i);
assertJrTutChapterNumber(i);
}
});

Expand Down Expand Up @@ -135,7 +127,7 @@ context("Navigation of per-method lesson", () => {
settleModalDialog("Make a copy");

cy.title().should("match", /Pytch: Copy of/);
assertChapterNumber(3);
assertJrTutChapterNumber(3);
cy.get('.LearnerTask[data-task-index="6"][data-task-kind="current"]');

// help-sidebar, lesson, keynav-help-sidebar
Expand Down Expand Up @@ -185,13 +177,13 @@ context("Navigation of per-method lesson", () => {
for (let i = 0; i !== 5; ++i) {
advanceToNextChapter(i);
}
assertChapterNumber(5);
assertJrTutChapterNumber(5);

cy.pytchSwitchProject("LESSON-LINKED-1");
assertChapterNumber(0);
assertJrTutChapterNumber(0);

cy.pytchSwitchProject("LESSON-LINKED-0");
assertChapterNumber(5);
assertJrTutChapterNumber(5);
});
});

Expand Down Expand Up @@ -331,7 +323,7 @@ context("Navigation of per-method lesson", () => {
assertHelpVisible();

getActivityBarTab("book").click();
assertChapterNumber(3);
assertJrTutChapterNumber(3);
assertNoHelp();

getActivityBarTab("circle-question").click();
Expand All @@ -357,3 +349,20 @@ context("launch demo from tutorial card", () => {
assertActorNames(["Stage", "Bowl", "Apple", "ScoreKeeper"]);
});
});

context("rejects wrong program-kind", () => {
beforeEach(() => {
cy.pytchResetDatabase();
cy.contains("My projects").click();
});

it("flat project but per-method tutorial", () => {
cy.pytchTryUploadZipfiles(["v4-flat-linked-to-jr-tutorial.zip"]);

// The error is caught in two places. To see the message we have to
// explicitly select the "lesson" activity.
cy.get('button[data-activity-bar-tab="lesson"]').click();

assertShowsLinkedContentError(/project.*flat.*tutorial.*per-method/);
});
});
20 changes: 19 additions & 1 deletion cypress/e2e/junior/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { deIndent } from "../../common/utils";

import { IconName } from "@fortawesome/fontawesome-common-types";
import { AceControllerMap } from "../../../src/skulpt-connection/code-editor";
import { launchProjectInListDropdownAction } from "../utils";
import { assertInIDE, launchProjectInListDropdownAction } from "../utils";
import { Actions } from "easy-peasy";
import { IActiveProject } from "../../../src/model/project";
import { assertNever, range } from "../../../src/utils";
Expand Down Expand Up @@ -746,3 +746,21 @@ export const assertTwoStateSwitchState = (
const expStateStr = expState.toString();
cy.get(selector).should("have.attr", "aria-checked", expStateStr);
};

/** Assert that a "per-method" tutorial is being displayed, showing the
* chapter with the given `expChapterNumber`. */
export function assertJrTutChapterNumber(expChapterNumber: number) {
assertInIDE("per-method");

cy.get(".Junior-LessonContent-HeaderBar .chapter-title").as("title");

if (expChapterNumber === 0) {
cy.get("@title").should("be.visible");
cy.get("@title").find(".chapter-number").should("not.exist");
return;
}

cy.get("@title")
.find(".chapter-number")
.should("have.text", `${expChapterNumber} —`);
}
Loading