fix(curriculum): revise user stories of Checkout Page lab (#61819)

Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
This commit is contained in:
Huyen Nguyen
2025-09-22 16:54:43 +07:00
committed by GitHub
parent 949ceff4e0
commit 8d1b3a67df

View File

@@ -18,9 +18,11 @@ demoType: onClick
1. You should have an image of an item in the first section with appropriate alternate text. You can use this image if you would like: `https://cdn.freecodecamp.org/curriculum/labs/cube.jpg`
1. You should have an `h2` element with the text `Payment Information` within the second section.
1. You should have a `form` element within the second section.
1. You should have an input with an `id` and `name` of `card-name` within your form and a `label` associated with it.
1. You should have an input with an `id` and `name` of `card-number` within your form and a `label` associated with it.
1. At least two of your input elements should be required and have an `aria-required` attribute set to `true`.
1. You should have an input with an `id` and `name` of `card-name`, and a `type` of `text` within your form and a `label` associated with it.
1. You should have an input with an `id` and `name` of `card-number`, and a `type` of `text` within your form and a `label` associated with it.
1. You should have at least two `input` elements with the `required` attribute.
1. You should include a `span` element with the text `*` and `aria-hidden` set to `true` inside the `label` element for each required input, so that required fields are visually indicated.
1. You should have a `p` element with a help text that explains the required card number format, placed immediately after the card number input. The `p` should have an `id` of `card-number-help` and be referenced by the card number input using `aria-describedby`.
# --hints--
@@ -82,6 +84,14 @@ assert.exists(secondSection?.querySelector('form input#card-name'));
assert.exists(secondSection?.querySelector('form input[name="card-name"]'));
```
Your card name input should have a `type` of `text`.
```js
const cardNameInput = document.getElementById('card-name');
assert.exists(cardNameInput);
assert.equal(cardNameInput.getAttribute('type'), 'text');
```
You should have an `input` element with an `id` and `name` of `card-number` within your form.
```js
@@ -90,6 +100,14 @@ assert.exists(secondSection?.querySelector('form input#card-number'));
assert.exists(secondSection?.querySelector('form input[name="card-number"]'));
```
Your card number input should have a `type` of `text`.
```js
const cardNumberInput = document.getElementById('card-number');
assert.exists(cardNumberInput);
assert.equal(cardNumberInput.getAttribute('type'), 'text');
```
All of your `input` elements that aren't a `type` of `submit` should have a `label` element associated with them.
```js
@@ -98,14 +116,68 @@ assert.isAtLeast(inputs.length, 1);
inputs.forEach(input => assert.exists(document.querySelector(`label[for="${input.id}"]`)));
```
At least two of your `input` elements should be required and have an `aria-required` attribute set to `true`.
You should have at least two `input` elements with the `required` attribute.
```js
const inputs = document.querySelectorAll('input');
const requiredInputs = Array.from(inputs).filter(input => input.required && input.getAttribute('aria-required') === 'true');
const requiredInputs = Array.from(inputs).filter(input => input.required);
assert.isAtLeast(requiredInputs?.length, 2)
```
You should include a `span` element with the text `*` inside the `label` element for each required input.
```js
const requiredInputs = Array.from(document.querySelectorAll('input'))
.filter(input => input.required);
assert.isNotEmpty(requiredInputs);
requiredInputs.forEach(input => {
const label = document.querySelector(`label[for="${input.id}"]`);
const span = label?.querySelector('span');
assert.equal(span?.textContent.trim(), '*');
});
```
Your `span` elements should have `aria-hidden` set to `true`.
```js
const requiredInputs = Array.from(document.querySelectorAll('input'))
.filter(input => input.required);
assert.isNotEmpty(requiredInputs);
requiredInputs.forEach(input => {
const label = document.querySelector(`label[for="${input.id}"]`);
const span = label?.querySelector('span');
assert.equal(span?.getAttribute('aria-hidden'), 'true');
});
```
You should have a `p` element with an `id` of `card-number-help` immediately after the card number input.
```js
const cardNumberInput = document.getElementById('card-number');
const cardNumberHelp = document.getElementById('card-number-help');
assert.exists(cardNumberHelp);
assert.equal(cardNumberInput.nextElementSibling, cardNumberHelp);
```
Your card number help text should not be empty.
```js
const cardNumberHelp = document.getElementById('card-number-help');
assert.isString(cardNumberHelp?.textContent);
assert.isAbove(cardNumberHelp?.textContent.trim().length, 0);
```
Your card number input should have `aria-describedby` set to `card-number-help`.
```js
const cardNumberInput = document.getElementById('card-number');
assert.equal(cardNumberInput.getAttribute('aria-describedby'), 'card-number-help');
```
# --seed--
@@ -152,20 +224,21 @@ assert.isAtLeast(requiredInputs?.length, 2)
<h2>Payment Information</h2>
<form action="/submit-payment" method="POST">
<div>
<label for="card-name">Cardholder Name</label>
<input type="text" id="card-name" name="card-name" required aria-required="true">
<label for="card-name">Cardholder Name <span aria-hidden="true">*</span></label>
<input type="text" id="card-name" name="card-name" required>
</div>
<div>
<label for="card-number">Card Number</label>
<input type="text" id="card-number" name="card-number" required aria-required="true">
<label for="card-number">Card Number <span aria-hidden="true">*</span></label>
<input type="text" id="card-number" name="card-number" aria-describedby="card-number-help" required>
<p id="card-number-help">Please enter your 16-digit card number without spaces or dashes.</p>
</div>
<div>
<label for="expiry-date">Expiry Date</label>
<input type="text" id="expiry-date" name="expiry-date" placeholder="MM/YY" required aria-required="true">
<label for="expiry-date">Expiry Date <span aria-hidden="true">*</span></label>
<input type="text" id="expiry-date" name="expiry-date" placeholder="MM/YY" required>
</div>
<div>
<label for="cvv">CVV</label>
<input type="text" id="cvv" name="cvv" required aria-required="true" aria-label="Card Verification Value">
<label for="cvv">CVV <span aria-hidden="true">*</span></label>
<input type="text" id="cvv" name="cvv" required aria-label="Card Verification Value">
</div>
<input type="submit" value="Place Order">
</form>