From 0e3b48ab284e43f4d78fd45dc21a01e4cfd72876 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 15 Jan 2025 10:45:00 +0100 Subject: [PATCH 01/14] Start setting up test --- test/system/bootcamp/editor_test.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/system/bootcamp/editor_test.rb diff --git a/test/system/bootcamp/editor_test.rb b/test/system/bootcamp/editor_test.rb new file mode 100644 index 0000000000..fa9299d616 --- /dev/null +++ b/test/system/bootcamp/editor_test.rb @@ -0,0 +1,26 @@ +require "application_system_test_case" + +module Bootcamp + class EditorTest < ApplicationSystemTestCase + test "shows to basic user" do + email = "#{SecureRandom.uuid}@test.com" + ubd = create :user_bootcamp_data, email:, paid_at: Time.current + user = create(:user, email:) + project = create :bootcamp_project + exercise = create :bootcamp_exercise, bootcamp_project: project + + # Always does this once by default anyway + User::Bootcamp::SubscribeToOnboardingEmails.expects(:defer).with(ubd).twice + + User::Bootstrap.(user) + assert user.reload.bootcamp_attendee? + + use_capybara_host do + sign_in!(user) + visit bootcamp_project_exercise_url(project, exercise) + + assert_text "Welcome to the Exercism Bootcamp!" + end + end + end +end From 3e9c7219ed4cebab5983ce332dbb0175d40f4d26 Mon Sep 17 00:00:00 2001 From: Jeremy Walker Date: Wed, 15 Jan 2025 12:34:02 +0000 Subject: [PATCH 02/14] Add setup for bootcamp system tests --- app/models/bootcamp/exercise.rb | 8 +- app/views/layouts/bootcamp-ui.haml | 5 - test/factories/bootcamp/exercises.rb | 5 + .../drawing/exercises/penguin/config.json | 110 ++++++++++++++++++ .../drawing/exercises/penguin/example.jiki | 43 +++++++ .../drawing/exercises/penguin/introduction.md | 3 + .../drawing/exercises/penguin/stub.jiki | 1 + .../drawing/exercises/penguin/task-1.md | 5 + test/system/bootcamp/editor_test.rb | 15 +-- 9 files changed, 177 insertions(+), 18 deletions(-) create mode 100644 test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json create mode 100644 test/repos/bootcamp_content/projects/drawing/exercises/penguin/example.jiki create mode 100644 test/repos/bootcamp_content/projects/drawing/exercises/penguin/introduction.md create mode 100644 test/repos/bootcamp_content/projects/drawing/exercises/penguin/stub.jiki create mode 100644 test/repos/bootcamp_content/projects/drawing/exercises/penguin/task-1.md diff --git a/app/models/bootcamp/exercise.rb b/app/models/bootcamp/exercise.rb index af316f6c4f..f8a5dd8681 100644 --- a/app/models/bootcamp/exercise.rb +++ b/app/models/bootcamp/exercise.rb @@ -50,6 +50,12 @@ def readonly_ranges private def file_contents(filename) - File.read(Rails.root / "bootcamp_content/projects/#{project.slug}/exercises/#{slug}/#{filename}") + File.read(root_dir / "projects/#{project.slug}/exercises/#{slug}/#{filename}") + end + + def root_dir + return Rails.root / "test/repos/bootcamp_content" if Rails.env.test? + + Rails.root / "bootcamp_content" end end diff --git a/app/views/layouts/bootcamp-ui.haml b/app/views/layouts/bootcamp-ui.haml index 1e65c8f5a7..fe0fdc3093 100644 --- a/app/views/layouts/bootcamp-ui.haml +++ b/app/views/layouts/bootcamp-ui.haml @@ -70,11 +70,6 @@ %meta{ name: "turbo-prefetch", content: "false" } %meta{ name: "user-id", content: current_user&.id } - %link{ href: "/manifest.json", rel: "manifest" } - %link{ href: "/icon.png", rel: "icon", type: "image/png" } - %link{ href: "/icon.svg", rel: "icon", type: "image/svg+xml" } - %link{ href: "/icon.png", rel: "apple-touch-icon" } - -# = javascript_include_tag "application", "data-turbo-track": "reload", type: "module", crossorigin: :anonymous = javascript_include_tag "bootcamp-ui-js", "data-turbo-track": "reload", type: "module", crossorigin: :anonymous %body{ class: body_class } diff --git a/test/factories/bootcamp/exercises.rb b/test/factories/bootcamp/exercises.rb index 5dfb3da732..b778a41931 100644 --- a/test/factories/bootcamp/exercises.rb +++ b/test/factories/bootcamp/exercises.rb @@ -7,4 +7,9 @@ description { "Exercise Description" } level_idx { (Bootcamp::Level.first || create(:bootcamp_level)).idx } end + + trait :penguin do + slug { "penguin" } + project { Bootcamp::Project.find_by(slug: "drawing") || create(:bootcamp_project, slug: "drawing") } + end end diff --git a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json new file mode 100644 index 0000000000..6743558a2a --- /dev/null +++ b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json @@ -0,0 +1,110 @@ +{ + "idx": 4, + "title": "Penguin", + "description": "Make the penguin symmetrical", + "project_type": "draw", + "level": 1, + "concepts": [], + "tests_type": "state", + "readonly_ranges": [], + "tasks": [ + { + "name": "Draw the scene", + "tests": [ + { + "slug": "draw-scence", + "name": "Make the penguin symmetrical.", + "description_html": "Fix all the TODO comments to make the penguin symmetrical.", + "function": "main", + "checks": [ + { + "name": "getRectangleAt(0, 0, 100, 100)", + "matcher": "toExist", + "error_html": "The sky has gone wrong." + }, + { + "name": "getRectangleAt(0, 70, 100, 30)", + "matcher": "toExist", + "error_html": "The ground has gone wrong." + }, + { + "name": "getEllipseAt(28, 55, 10, 25)", + "matcher": "toExist", + "error_html": "The left wing doesn't seem right." + }, + { + "name": "getEllipseAt(72, 55, 10, 25)", + "matcher": "toExist", + "error_html": "The right wing doesn't seem right." + }, + { + "name": "getEllipseAt(50, 53, 25, 40)", + "matcher": "toExist", + "error_html": "The outer body has gone wrong." + }, + { + "name": "getEllipseAt(50, 50, 21, 39)", + "matcher": "toExist", + "error_html": "The inner body has gone wrong." + }, + { + "name": "getCircleAt(50, 31, 23)", + "matcher": "toExist", + "error_html": "The head has gone wrong." + }, + { + "name": "getEllipseAt(41, 32, 11, 14)", + "matcher": "toExist", + "error_html": "The left side of the face doesn't look right." + }, + { + "name": "getEllipseAt(59, 32, 11, 14)", + "matcher": "toExist", + "error_html": "The right side of the face doesn't look right." + }, + { + "name": "getEllipseAt(50, 40, 16, 11)", + "matcher": "toExist", + "error_html": "The lower part of the face doesn't look right." + }, + { + "name": "getCircleAt(42, 33, 3)", + "matcher": "toExist", + "error_html": "The left eye seems off." + }, + { + "name": "getCircleAt(43, 34, 1)", + "matcher": "toExist", + "error_html": "The left iris seems off." + }, + { + "name": "getCircleAt(58, 33, 3)", + "matcher": "toExist", + "error_html": "The right eye seems off." + }, + { + "name": "getCircleAt(57, 34, 1)", + "matcher": "toExist", + "error_html": "The right iris seems off." + }, + { + "name": "getEllipseAt(40, 93, 7, 4)", + "matcher": "toExist", + "error_html": "The left foot's gone astray." + }, + { + "name": "getEllipseAt(60, 93, 7, 4)", + "matcher": "toExist", + "error_html": "The right foot's not right." + }, + { + "name": "getTriangleAt(46, 38, 54, 38, 50, 47)", + "matcher": "toExist", + "error_html": "The nose isn't right." + } + ] + } + ] + } + ] +} diff --git a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/example.jiki b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/example.jiki new file mode 100644 index 0000000000..9d57b7b4bd --- /dev/null +++ b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/example.jiki @@ -0,0 +1,43 @@ +// Light blue background +fill_color_hex("#ADD8E6") +rectangle(0, 0, 100, 100) + +// Ground +fill_color_hex("#ffffff") // Ice ground +rectangle(0, 70, 100, 30) // Ice ground + +// Penguin wings +fill_color_hex("#000000") // Black +ellipse(28, 55, 10, 25) // Left wing +ellipse(72, 55, 10, 25) // Right wing + +// Penguin body +fill_color_hex("#000000") // Black for the body +ellipse(50, 53, 25, 40) // Outer body (oval shape) +fill_color_hex("#ffffff") // White for the belly +ellipse(50, 50, 21, 39) // Inner belly (oval shape) + +// Penguin head +fill_color_hex("#000000") // Black +circle(50, 31, 23) // Head (circle) +fill_color_hex("#ffffff") // White for the face +ellipse(41, 32, 11, 14) // Left part of the face +ellipse(59, 32, 11, 14) // Right part of the face +ellipse(50, 40, 16, 11) // Lower part of the face + +// Penguin eyes +fill_color_hex("#000000") // Black +circle(42, 33, 3) // Left eye +fill_color_hex("#ffffff") // White +circle(43, 34, 1) // Left iris + +fill_color_hex("#000000") // Black +circle(58, 33, 3) // Right eye +fill_color_hex("#ffffff") // White +circle(57, 34, 1) // Right iris + +// Feet +fill_color_hex("#FFA500") +ellipse(40, 93, 7, 4) +ellipse(60, 93, 7, 4) +triangle(46, 38, 54, 38, 50, 47) \ No newline at end of file diff --git a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/introduction.md b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/introduction.md new file mode 100644 index 0000000000..df35aa51d9 --- /dev/null +++ b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/introduction.md @@ -0,0 +1,3 @@ +# Introduction + +This is fun! diff --git a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/stub.jiki b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/stub.jiki new file mode 100644 index 0000000000..5ab2f8a432 --- /dev/null +++ b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/stub.jiki @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/task-1.md b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/task-1.md new file mode 100644 index 0000000000..c9fc02faac --- /dev/null +++ b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/task-1.md @@ -0,0 +1,5 @@ +Follow the `TODO` comments to make the penguin symmetrical. + +As you get each bit right, tidy up the comments by removing the `TODO` and replacing it with a nicer comment. + +Use the "Check Scenarios" button regularly, and have fun! diff --git a/test/system/bootcamp/editor_test.rb b/test/system/bootcamp/editor_test.rb index fa9299d616..ff9aacffba 100644 --- a/test/system/bootcamp/editor_test.rb +++ b/test/system/bootcamp/editor_test.rb @@ -3,21 +3,12 @@ module Bootcamp class EditorTest < ApplicationSystemTestCase test "shows to basic user" do - email = "#{SecureRandom.uuid}@test.com" - ubd = create :user_bootcamp_data, email:, paid_at: Time.current - user = create(:user, email:) - project = create :bootcamp_project - exercise = create :bootcamp_exercise, bootcamp_project: project - - # Always does this once by default anyway - User::Bootcamp::SubscribeToOnboardingEmails.expects(:defer).with(ubd).twice - - User::Bootstrap.(user) - assert user.reload.bootcamp_attendee? + user = create(:user, bootcamp_attendee: true) + exercise = create :bootcamp_exercise, :penguin use_capybara_host do sign_in!(user) - visit bootcamp_project_exercise_url(project, exercise) + visit bootcamp_project_exercise_url(exercise.project, exercise) assert_text "Welcome to the Exercism Bootcamp!" end From d6302b9757edc01fae471f0c8401b9eb6ec5aacb Mon Sep 17 00:00:00 2001 From: Aron Demeter <66035744+dem4ron@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:22:05 +0100 Subject: [PATCH 03/14] Basic render test (#7402) * Fix config, add selectors, add basic test of rendering * Add very basic render test --- .../CodeMirror/CodeMirror.tsx | 2 +- .../ControlButtons/CheckScenariosButton.tsx | 1 + .../ControlButtons/ControlButtons.tsx | 5 ++- .../SolveExercisePage/Scrubber/Scrubber.tsx | 4 +-- .../SolveExercisePage/SolveExercisePage.tsx | 6 ++-- .../TaskPreview/TaskPreview.tsx | 2 +- .../SolveExercisePage/Tasks/TaskList.tsx | 2 +- .../SolveExercisePage/Tasks/Tasks.tsx | 4 +-- .../InspectedTestResultView.tsx | 2 +- .../generateExpects.ts | 1 + .../drawing/exercises/penguin/config.json | 34 +++++++++---------- test/system/bootcamp/editor_test.rb | 12 +++++-- 12 files changed, 45 insertions(+), 30 deletions(-) diff --git a/app/javascript/components/bootcamp/SolveExercisePage/CodeMirror/CodeMirror.tsx b/app/javascript/components/bootcamp/SolveExercisePage/CodeMirror/CodeMirror.tsx index 88f27a15de..c6f869e021 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/CodeMirror/CodeMirror.tsx +++ b/app/javascript/components/bootcamp/SolveExercisePage/CodeMirror/CodeMirror.tsx @@ -278,7 +278,7 @@ export const CodeMirror = forwardRef(function _CodeMirror( return (
{ handleRunCode() diff --git a/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx b/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx index 679a44079c..bc92733567 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx +++ b/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx @@ -7,7 +7,10 @@ import { assembleClassNames } from '@/utils/assemble-classnames' function _ControlButtons({ handleRunCode }: { handleRunCode: () => void }) { return ( -
+
{/* Run the tests with this button */} {/* These buttons let you select a test/scenario that you want to inspect. */} diff --git a/app/javascript/components/bootcamp/SolveExercisePage/Scrubber/Scrubber.tsx b/app/javascript/components/bootcamp/SolveExercisePage/Scrubber/Scrubber.tsx index c637d1edea..195d677678 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/Scrubber/Scrubber.tsx +++ b/app/javascript/components/bootcamp/SolveExercisePage/Scrubber/Scrubber.tsx @@ -38,7 +38,7 @@ function Scrubber({ return (
{ // we wanna focus the range input, so keyboard shortcuts work @@ -60,7 +60,7 @@ function Scrubber({ /> )} +
{exercise.config.testsType === 'io' ? ( ) : ( diff --git a/app/javascript/components/bootcamp/SolveExercisePage/Tasks/TaskList.tsx b/app/javascript/components/bootcamp/SolveExercisePage/Tasks/TaskList.tsx index 8e4565fd80..c4db1e122d 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/Tasks/TaskList.tsx +++ b/app/javascript/components/bootcamp/SolveExercisePage/Tasks/TaskList.tsx @@ -17,7 +17,7 @@ export function TaskList({ tasks }: { tasks: Task[] }) { function Task({ task, onClick }: { task: Task; onClick: () => void }) { return ( -
+
+

Your Tasks

-
+
{numberOfCompletedTasks}/{numberOfTasks}
diff --git a/app/javascript/components/bootcamp/SolveExercisePage/TestResultsView/InspectedTestResultView.tsx b/app/javascript/components/bootcamp/SolveExercisePage/TestResultsView/InspectedTestResultView.tsx index 37a6159e7f..687188634c 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/TestResultsView/InspectedTestResultView.tsx +++ b/app/javascript/components/bootcamp/SolveExercisePage/TestResultsView/InspectedTestResultView.tsx @@ -50,7 +50,7 @@ export function InspectedTestResultViewLHS({ [flatPreviewTaskTests, result.testIndex] ) return ( -
+

Scenario: diff --git a/app/javascript/components/bootcamp/SolveExercisePage/test-runner/generateAndRunTestSuite/generateExpects.ts b/app/javascript/components/bootcamp/SolveExercisePage/test-runner/generateAndRunTestSuite/generateExpects.ts index a78581b21f..11fa4283f3 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/test-runner/generateAndRunTestSuite/generateExpects.ts +++ b/app/javascript/components/bootcamp/SolveExercisePage/test-runner/generateAndRunTestSuite/generateExpects.ts @@ -78,6 +78,7 @@ function generateExpectsForStateTests( const errorHtml = check.errorHtml?.replaceAll('%actual%', actual) || '' + console.log('matcher', matcher, 'checkvalue', check.value, 'actual', actual) return expect({ ...check, testsType: 'state', diff --git a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json index 6743558a2a..8dccbcffcb 100644 --- a/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json +++ b/test/repos/bootcamp_content/projects/drawing/exercises/penguin/config.json @@ -19,87 +19,87 @@ "checks": [ { "name": "getRectangleAt(0, 0, 100, 100)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The sky has gone wrong." }, { "name": "getRectangleAt(0, 70, 100, 30)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The ground has gone wrong." }, { "name": "getEllipseAt(28, 55, 10, 25)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The left wing doesn't seem right." }, { "name": "getEllipseAt(72, 55, 10, 25)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The right wing doesn't seem right." }, { "name": "getEllipseAt(50, 53, 25, 40)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The outer body has gone wrong." }, { "name": "getEllipseAt(50, 50, 21, 39)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The inner body has gone wrong." }, { "name": "getCircleAt(50, 31, 23)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The head has gone wrong." }, { "name": "getEllipseAt(41, 32, 11, 14)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The left side of the face doesn't look right." }, { "name": "getEllipseAt(59, 32, 11, 14)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The right side of the face doesn't look right." }, { "name": "getEllipseAt(50, 40, 16, 11)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The lower part of the face doesn't look right." }, { "name": "getCircleAt(42, 33, 3)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The left eye seems off." }, { "name": "getCircleAt(43, 34, 1)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The left iris seems off." }, { "name": "getCircleAt(58, 33, 3)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The right eye seems off." }, { "name": "getCircleAt(57, 34, 1)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The right iris seems off." }, { "name": "getEllipseAt(40, 93, 7, 4)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The left foot's gone astray." }, { "name": "getEllipseAt(60, 93, 7, 4)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The right foot's not right." }, { "name": "getTriangleAt(46, 38, 54, 38, 50, 47)", - "matcher": "toExist", + "matcher": "toBeDefined", "error_html": "The nose isn't right." } ] diff --git a/test/system/bootcamp/editor_test.rb b/test/system/bootcamp/editor_test.rb index ff9aacffba..b39087b5ec 100644 --- a/test/system/bootcamp/editor_test.rb +++ b/test/system/bootcamp/editor_test.rb @@ -2,7 +2,7 @@ module Bootcamp class EditorTest < ApplicationSystemTestCase - test "shows to basic user" do + test "things render" do user = create(:user, bootcamp_attendee: true) exercise = create :bootcamp_exercise, :penguin @@ -10,7 +10,15 @@ class EditorTest < ApplicationSystemTestCase sign_in!(user) visit bootcamp_project_exercise_url(exercise.project, exercise) - assert_text "Welcome to the Exercism Bootcamp!" + assert_selector("#bootcamp-cm-editor") + assert_selector("[data-ci='check-scenarios-button']") + assert_selector("[data-ci='control-buttons']") + assert_selector("[data-ci='task-preview']") + refute_selector("[data-ci='inspected-test-result-view']") + assert_selector(".page-header") + assert_selector(".page-body-rhs") + assert_selector(".scenario-rhs") + assert_text "This is fun!" end end end From 5e3054735f0a83dc51e61288eb24ca61b7703653 Mon Sep 17 00:00:00 2001 From: Aron Demeter <66035744+dem4ron@users.noreply.github.com> Date: Wed, 29 Jan 2025 14:28:23 +0100 Subject: [PATCH 04/14] Add more kinds of exercises (#7409) --- .../ControlButtons/ControlButtons.tsx | 1 + test/factories/bootcamp/exercises.rb | 10 +++ .../maze/exercises/manual-solve/config.json | 52 ++++++++++++++ .../maze/exercises/manual-solve/example.jiki | 21 ++++++ .../exercises/manual-solve/introduction.md | 11 +++ .../maze/exercises/manual-solve/stub.jiki | 6 ++ .../maze/exercises/manual-solve/task-1.md | 8 +++ .../numbers/exercises/even-or-odd/config.json | 70 +++++++++++++++++++ .../exercises/even-or-odd/example.jiki | 7 ++ .../exercises/even-or-odd/introduction.md | 32 +++++++++ .../numbers/exercises/even-or-odd/stub.jiki | 3 + .../numbers/exercises/even-or-odd/task-1.md | 3 + .../numbers/exercises/even-or-odd/task-2.md | 3 + .../numbers/exercises/even-or-odd/task-3.md | 3 + test/system/bootcamp/editor_test.rb | 33 +++++++++ 15 files changed, 263 insertions(+) create mode 100644 test/repos/bootcamp_content/projects/maze/exercises/manual-solve/config.json create mode 100644 test/repos/bootcamp_content/projects/maze/exercises/manual-solve/example.jiki create mode 100644 test/repos/bootcamp_content/projects/maze/exercises/manual-solve/introduction.md create mode 100644 test/repos/bootcamp_content/projects/maze/exercises/manual-solve/stub.jiki create mode 100644 test/repos/bootcamp_content/projects/maze/exercises/manual-solve/task-1.md create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/config.json create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/example.jiki create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/introduction.md create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/stub.jiki create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/task-1.md create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/task-2.md create mode 100644 test/repos/bootcamp_content/projects/numbers/exercises/even-or-odd/task-3.md diff --git a/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx b/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx index bc92733567..93f8632572 100644 --- a/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx +++ b/app/javascript/components/bootcamp/SolveExercisePage/ControlButtons/ControlButtons.tsx @@ -37,6 +37,7 @@ function PreviewTestButtons() {
{flatPreviewTaskTests.map((taskTest, testIdx) => (