Skip to content

Commit 02d41f2

Browse files
authored
✨ Quiz and Playwright Updates (#133)
1 parent 9fe28df commit 02d41f2

12 files changed

+89
-13
lines changed

.env.example

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PLAYWRIGHT_EXECUTION_ENV="PROD" # "DEV" or "PROD"

README.md

+18
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ Sitemap file gets updated automatically by this awesome package - [next-sitemap]
9494

9595
## 🧪 Playwright Tests
9696

97+
### Introduction
98+
99+
- In Github Actions, we are using docker images to run the tests.
100+
- Refer to [PR that updates playwright actions](https://github.com/payapula/blog/pull/111/commits/b78b8864abbe3b979f7c1a3c8be1476c588f1872)
101+
- [Playwright documentation link](https://playwright.dev/docs/ci#via-containers)
102+
- This ensures the screenshot testing is consistent in local and in CI environments.
103+
104+
### Env Variables
105+
106+
- To properly switch environments, we have `.env.local` file.
107+
- Refer to `.env.example` file and `playwright.config.ts` file to know how this env file is being read.
108+
- DEV mode will use `html` report, compared to `list` report in production.
109+
- In order to test Production URL, update the `.env.local` file appropriately and do `npx playwright test`.
110+
97111
### Screenshots
98112

99113
Its tricky to generate screenshots when tests are running in Github actions.
@@ -109,6 +123,10 @@ screenshots via docker in local.
109123

110124
Run `npx playwright test --update-snapshots`, it will generate new screenshot files for `-darwin.png`
111125

126+
> [!NOTE]
127+
> These screenshots are not validated in Github actions, as we are using docker container to run the
128+
> test in Github actions. This `-darwin.png` screenshots are only for local testing purposes.
129+
112130
##### For CI (linux)
113131

114132
1. On root of the project directory, open a terminal (/blog).

_quiz/react-is-just-javascript.mdx

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ keywords: 'React,Javascript,Beginner'
3434
</Choise>
3535
</Choises>
3636
<Answer>
37-
There are no magic here.
37+
As expected in Javascript.
3838
</Answer>
3939
</QuestionSet>
4040
<QuestionSet>
@@ -67,7 +67,7 @@ keywords: 'React,Javascript,Beginner'
6767
</Choise>
6868
</Choises>
6969
<Answer>
70-
Again, No magic. React would render a `div` with the children "Hello World".
70+
React would render a `div` with the children "Hello World".
7171
</Answer>
7272
</QuestionSet>
7373
<QuestionSet>
@@ -94,8 +94,6 @@ keywords: 'React,Javascript,Beginner'
9494
</Choise>
9595
</Choises>
9696
<Answer>
97-
`React.createElement("h1", null, "Hello World")`
98-
9997
Since we have `Hello World` string, the third argument of createElement would be a simple "string".
10098
</Answer>
10199
</QuestionSet>

components/mdx/components/quiz/question-set.tsx

+40-3
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,23 @@ export function QuestionSet({
2020
}: QuestionSetProps) {
2121
const [value, setValue] = React.useState('');
2222
const validAnswer = React.useRef<string>();
23+
const validAnswerText = React.useRef<string>();
2324

2425
const [Question, Choises, Answer] = Children.toArray(children);
2526

2627
//@ts-ignore
2728
const choiseElements = Children.map(Choises.props.children, (child, index) => {
2829
if (child.props?.isAnswer) {
2930
validAnswer.current = index.toString();
31+
validAnswerText.current = child.props.children;
3032
}
33+
const value = index.toString();
34+
const ariaLabel = `label_${value}`;
3135
return (
32-
<RadioItem value={index.toString()} disabled={answerSubmitted}>
33-
<div className="flex items-baseline [&>p]:mt-0">{child.props.children}</div>
36+
<RadioItem value={value} disabled={answerSubmitted} ariaLabel={ariaLabel}>
37+
<div className="flex items-baseline [&>p]:mt-0" id={ariaLabel}>
38+
{child.props.children}
39+
</div>
3440
</RadioItem>
3541
);
3642
});
@@ -63,11 +69,42 @@ export function QuestionSet({
6369
</QuizNavigationButton>
6470
</form>
6571
{answerSubmitted && <AnswerStatus isCorrect={isCorrect} />}
66-
{answerSubmitted ? Answer : null}
72+
{answerSubmitted && (
73+
<AnswerReveal answerText={validAnswerText.current} isCorrect={isCorrect} />
74+
)}
75+
{answerSubmitted ? <AnswerMeta answerMeta={Answer} /> : null}
6776
</CardWrapper>
6877
);
6978
}
7079

80+
function AnswerReveal({
81+
answerText,
82+
isCorrect
83+
}: {
84+
isCorrect: boolean;
85+
answerText: React.ReactNode;
86+
}) {
87+
const userChoseCorrectAnswer = isCorrect;
88+
const textMessage = userChoseCorrectAnswer
89+
? `✅ You chose the correct answer`
90+
: `Oops! The correct answer is `;
91+
return (
92+
<div className="mt-5 flex flex-col items-start gap-1">
93+
<p className="text-center font-bold">{textMessage}</p>
94+
{answerText}
95+
</div>
96+
);
97+
}
98+
99+
function AnswerMeta({ answerMeta }: { answerMeta: React.ReactNode }) {
100+
return (
101+
<div className="mt-5">
102+
<p className="text-left font-bold">Explanation:</p>
103+
{answerMeta}
104+
</div>
105+
);
106+
}
107+
71108
function AnswerStatus({ isCorrect }: { isCorrect: boolean }) {
72109
return (
73110
<p className="mt-5 text-center font-bold">

components/shadcn/radio-item.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ import { cn } from '@/lib/utils';
55
export function RadioItem({
66
children,
77
disabled,
8-
value
8+
value,
9+
ariaLabel
910
}: {
1011
value: string;
1112
disabled: boolean;
1213
children: React.ReactNode;
14+
ariaLabel: string;
1315
}) {
1416
return (
1517
<div>
1618
<Label
17-
htmlFor={value}
1819
/**
1920
* labelChecked is styled from globals.css
2021
*/
@@ -26,7 +27,7 @@ export function RadioItem({
2627
<RadioGroupItem
2728
disabled={disabled}
2829
value={value}
29-
id={value}
30+
aria-labelledby={ariaLabel}
3031
className={cn(
3132
`data-checked:scale-150 data-checked:bg-teal-300 dark:data-checked:bg-orange-700`,
3233
{

package-lock.json

+17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"clsx": "^2.1.1",
3030
"cross-env": "^7.0.3",
3131
"date-fns": "2.10.0",
32+
"dotenv": "^16.4.5",
3233
"git-date-extractor": "^4.0.1",
3334
"gray-matter": "4.0.2",
3435
"next": "^12.2.3",

playwright.config.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { defineConfig, devices } from '@playwright/test';
2+
import dotenv from 'dotenv';
3+
import path from 'path';
24
import siteConfig from 'configs/site-configs';
35

46
/**
57
* Read environment variables from file.
68
* https://github.com/motdotla/dotenv
9+
* https://playwright.dev/docs/test-parameterize#env-files
710
*/
8-
// require('dotenv').config();
11+
dotenv.config({ path: path.resolve(__dirname, '.env.local') });
912

10-
const IS_DEV_MODE = false;
13+
const IS_DEV_MODE = process.env.PLAYWRIGHT_EXECUTION_ENV === 'DEV';
1114
const BUILD_PORT = 3002;
1215

1316
/**
Loading
Loading
Loading

tests/quiz/all.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ test('Quiz Page Navigation Tests', async ({ page }) => {
2424
await expect(page.getByRole('button', { name: 'Submit' })).toBeEnabled();
2525
await page.getByRole('button', { name: 'Submit' }).click();
2626
await assertIncorrectAnswer(page);
27-
await testVisible(page.getByText('There are no magic here.'));
27+
await testVisible(page.getByText('As expected in Javascript.'));
2828
await moveToNextPage(page);
2929

3030
await page.locator('label').filter({ hasText: '<div>Hello World</div>' }).click();

0 commit comments

Comments
 (0)