feat(curriculum): add more validation of table structure to Book Inventory App lab (#64647)

Co-authored-by: Krzysztof G. <60067306+gikf@users.noreply.github.com>
Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
majestic-owl448
2026-01-14 07:00:47 +01:00
committed by GitHub
parent f7f6e9d3ac
commit fb7bfdd587
@@ -42,23 +42,27 @@ assert.equal(document.querySelector('h1')?.innerText.trim(), 'Book Inventory');
You should have only one `h1` element.
```js
assert.equal(document.querySelectorAll('h1')?.length, 1);
assert.lengthOf(document.querySelectorAll('h1'), 1);
```
You should have a `table` element.
```js
assert.equal(document.querySelectorAll('table')?.length, 1);
assert.lengthOf(document.querySelectorAll('table'), 1);
```
Your `table` element should have five columns.
You should have one `thead` element and one `tbody` element inside `table`.
```js
const rows = document.querySelectorAll('tr');
assert.isNotEmpty(rows);
for (const row of rows) {
assert.equal(row.children.length, 5);
}
assert.lengthOf(document.querySelectorAll("table > thead"), 1);
assert.lengthOf(document.querySelectorAll("table > tbody"), 1);
```
Inside the `thead` there should be one `tr` with 5 `th` elements.
```js
assert.lengthOf(document.querySelectorAll("table > thead > tr"), 1);
assert.lengthOf(document.querySelectorAll("table > thead > tr > th"), 5);
```
Your first column should have the text `Title` as the heading.
@@ -98,11 +102,21 @@ const rows = document.querySelectorAll('tr');
assert.isAtLeast(rows.length, 4);
```
Each row should always have 5 columns.
```js
const rows = document.querySelectorAll('tbody tr');
assert.isNotEmpty(rows);
for (const row of rows) {
assert.lengthOf(row.children, 5);
}
```
Each table row except the heading row should have either the class `read`, `to-read`, or `in-progress`.
```js
const rows = document.querySelectorAll('tr');
assert.isAtLeast(rows.length, 4);
assert.isNotEmpty(rows);
for (let i = 1; i < rows.length; i++) {
const classList = [...rows[i].classList];
const currentProgress = classList[0];
@@ -114,7 +128,7 @@ for (let i = 1; i < rows.length; i++) {
```js
const statusColumnData = document.querySelectorAll('td:nth-child(4)');
assert.isAbove(statusColumnData.length, 0);
assert.isNotEmpty(statusColumnData);
for (let e of statusColumnData) {
assert.equal(e?.children[0]?.tagName, 'SPAN');
}
@@ -124,7 +138,7 @@ Each `span` element of the `Status` column should have the class of `status`.
```js
const statusSpans = document.querySelectorAll('tr td:nth-child(4) :first-child');
assert.isAbove(statusSpans.length, 0);
assert.isNotEmpty(statusSpans);
for (let e of statusSpans) {
assert.isTrue(e.classList.contains('status'));
}
@@ -135,7 +149,7 @@ Each `.status` element should have the text `Read`, `To Read`, or `In Progress`,
```js
const statusSpans = document.querySelectorAll('tr td:nth-child(4) :first-child');
const rows = Array.from(document.querySelectorAll('tr')).slice(1);
assert.isAbove(statusSpans.length, 0);
assert.isNotEmpty(statusSpans);
for (let i = 0; i < rows.length; i++) {
switch (statusSpans[i]?.innerText.trim()) {
case 'Read':
@@ -157,7 +171,7 @@ for (let i = 0; i < rows.length; i++) {
```js
const rateColumnData = document.querySelectorAll('tr td:last-child');
assert.isAbove(rateColumnData.length, 0);
assert.isNotEmpty(rateColumnData);
for (let e of rateColumnData) {
assert.equal(e.children[0]?.tagName, 'SPAN')
}
@@ -167,7 +181,7 @@ Each `span` element which is a direct child of a `td` element of the `Rate` colu
```js
const rateSpans = document.querySelectorAll('tr td:last-child > span:first-child');
assert.isAbove(rateSpans.length, 0);
assert.isNotEmpty(rateSpans);
for (let e of rateSpans) {
assert.equal(e.classList[0], 'rate');
}
@@ -177,7 +191,7 @@ Each `.rate` element should contain three empty `span` elements.
```js
const rateSpans = document.getElementsByClassName('rate');
assert.isAbove(rateSpans.length, 0);
assert.isNotEmpty(rateSpans);
for (let e of rateSpans) {
assert.equal(e.children.length, 3);
for (let child of e.children) {
@@ -191,7 +205,7 @@ for (let e of rateSpans) {
```js
const readBooksRates = document.querySelectorAll('.read .rate');
assert.isAbove(readBooksRates.length, 0);
assert.isNotEmpty(readBooksRates);
for (let e of readBooksRates) {
assert.oneOf(e.classList[1], ['one', 'two', 'three']);
}