Skip to content

Commit

Permalink
Added OG image, nav image, unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Doughty committed Sep 5, 2024
1 parent bfebc6c commit 3973288
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 6 deletions.
4 changes: 2 additions & 2 deletions content/body/load-more.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<p>Category grids are typically straightforward components. However, incorporating a "load more" button introduces additional complexity, particularly when ensuring that these components remain accessible. The key takeaway from this example is understanding how the "load more" functionality operates. Notably, when additional category tiles are loaded, the user's focus is returned to the first tile in the newly loaded set. This approach allows users to seamlessly continue from where they left off before clicking the "load more" button.</p>

<div id="example1" class="enable-example">
<p id="view-count" aria-live="polite">Showing 3 of 9 Categories</p>
<p id="category-count" aria-live="polite">Showing 3 of 9 Categories</p>

<section id="view-grid">
<div class="view-tile">
Expand Down Expand Up @@ -59,7 +59,7 @@
"replaceHtmlRules": {},
"steps": [{
"label": "Add a product counter and add the aria-live attribute",
"highlight": "%OPENCLOSECONTENTTAG%p id=\"view-count\"",
"highlight": "%OPENCLOSECONTENTTAG%p id=\"category-count\"",
"notes": "It's a good idea to tell users how many products they're viewing out of the total number of products. We add the aria-live attribute set to polite to ensure that when it updates, it will be read out by the screen reader after the focused element is read."
},
{
Expand Down
2 changes: 1 addition & 1 deletion css/load-more.css
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
}
}
#product-count,
#view-count {
#category-count {
text-align: center;
}
#load-more-btn,
Expand Down
Binary file added images/main-menu/load-more.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/main-menu/load-more.webp
Binary file not shown.
Binary file added images/posters/load-more.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion js/demos/load-more/load-more.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ new ExampleGrid({
loadMoreBtn: 'view-more-btn',
resetBtn: 'view-reset-btn',
productGrid: 'view-grid',
countText: 'view-count',
countText: 'category-count',
tileClass: 'view-tile',
focusClass: 'view-details-link',
});
254 changes: 254 additions & 0 deletions js/test/load-more.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
'use strict';
import config from './test-config.js';

const exampleImages1 = '#example1 img';
const exampleImages2 = '#example2 img';

describe('Load More Tests', () => {
it('Example 1 should have images with non-empty alt tags', async () => {
await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example1');

const images = await page.$$eval(exampleImages1, (imgs) =>
imgs.map((img) => ({
src: img.src,
alt: img.alt,
})),
);

images.forEach((image) => {
expect(image.src).not.toBe('');
expect(image.alt).not.toBe('');
});
});

it('Example 1 should initalize with "Showing 3 of 9 Categories" and have aria-live polite', async () => {
await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example1');

const domInfo = await page.evaluate(() => {
const categoryCount = document.getElementById('category-count');

return {
hasProperCountText:
categoryCount.innerText === 'Showing 3 of 9 Categories',
hasAriaLive:
categoryCount.getAttribute('aria-live') === 'polite',
};
});

expect(domInfo.hasProperCountText).toBe(true);
expect(domInfo.hasAriaLive).toBe(true);
});

it('Example 1 keyboard support for "View More Categories" and "Reset Category Grid Demo" buttons', async () => {
const numTabPress = 3;
await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example1');

let domInfo;

// Start on the first category tile
domInfo = await page.evaluate(() => {
const firstTile = document.querySelector('.view-details-link');
firstTile.focus();
return {
isFirstTileFocused: document.activeElement === firstTile,
};
});

expect(domInfo.isFirstTileFocused).toBe(true);

// Tab to the "View More Categories" button and press it to load the first new set
for (let i = 0; i < numTabPress; i++) {
await page.keyboard.press('Tab');
}
await page.keyboard.press('Enter');

domInfo = await page.evaluate(() => {
const allTiles = Array.from(
document.querySelectorAll('.view-details-link'),
);
return {
isFirstTileInNewSetFocused:
document.activeElement === allTiles[3],
};
});

expect(domInfo.isFirstTileInNewSetFocused).toBe(true);

// Expect the counter to update
domInfo = await page.evaluate(() => {
const countText = document.querySelector('#category-count');
return {
isCountTextUpdated:
countText.innerHTML === 'Showing 6 of 9 Categories',
};
});

expect(domInfo.isCountTextUpdated).toBe(true);

// Tab to the "View More Categories" button and press it to load the second new set
for (let i = 0; i < numTabPress; i++) {
await page.keyboard.press('Tab');
}
await page.keyboard.press('Enter');

// Tab to the "Reset Category Grid Demo"
for (let i = 0; i < numTabPress; i++) {
await page.keyboard.press('Tab');
}
await page.keyboard.press('Enter');

// Expect the first tile to be selected after resetting the demo
domInfo = await page.evaluate(() => {
const allTiles = Array.from(
document.querySelectorAll('.view-details-link'),
);
return {
isFocusReset: document.activeElement === allTiles[0],
};
});

expect(domInfo.isFocusReset).toBe(true);
});

it('Example 2 should have images with non-empty alt tags', async () => {
await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example2');

const images = await page.$$eval(exampleImages2, (imgs) =>
imgs.map((img) => ({
src: img.src,
alt: img.alt,
})),
);

images.forEach((image) => {
expect(image.src).not.toBe('');
expect(image.alt).not.toBe('');
});
});

it('Example 2 should have a proper role and aria-labelledby assigned', async () => {
await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example2');

const domInfo = await page.evaluate(() => {
const tiles = Array.from(
document.querySelectorAll('.product-tile'),
);

return {
hasGroupRole: tiles.every(
(tile) => tile.getAttribute('role') === 'group',
),
hasAriaLabelledBy: tiles.every(
(tile) => tile.getAttribute('aria-labelledby') !== '',
),
};
});

expect(domInfo.hasGroupRole).toBe(true);
expect(domInfo.hasAriaLabelledBy).toBe(true);
});

it('Example 2 should initalize with "Showing 3 of 9 Products" and have aria-live polite', async () => {
await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example2');

const domInfo = await page.evaluate(() => {
const productCount = document.getElementById('product-count');

return {
hasProperCountText:
productCount.innerText === 'Showing 3 of 9 Products',
hasAriaLive:
productCount.getAttribute('aria-live') === 'polite',
};
});

expect(domInfo.hasProperCountText).toBe(true);
expect(domInfo.hasAriaLive).toBe(true);
});

it('Example 2 keyboard support for "Load More Products" and "Reset Product Grid Demo" buttons', async () => {
const numTabPress = 6;

await page.goto(`${config.BASE_URL}/load-more.php`);

await page.waitForSelector('#example2');

let domInfo;

// Start on the first category tile
domInfo = await page.evaluate(() => {
const firstTile = document.querySelector('.product-details-link');
firstTile.focus();
return {
isFirstTileFocused: document.activeElement === firstTile,
};
});

expect(domInfo.isFirstTileFocused).toBe(true);

// Tab to the "View More Categories" button and press it to load the first new set
for (let i = 0; i < numTabPress; i++) {
await page.keyboard.press('Tab');
}
await page.keyboard.press('Enter');

domInfo = await page.evaluate(() => {
const allTiles = Array.from(
document.querySelectorAll('.product-details-link'),
);
return {
isFirstTileInNewSetFocused:
document.activeElement === allTiles[3],
};
});

expect(domInfo.isFirstTileInNewSetFocused).toBe(true);

// Expect the counter to update
domInfo = await page.evaluate(() => {
const countText = document.querySelector('#product-count');
return {
isCountTextUpdated:
countText.innerHTML === 'Showing 6 of 9 Products',
};
});

expect(domInfo.isCountTextUpdated).toBe(true);

// Tab to the "View More Categories" button and press it to load the second new set
for (let i = 0; i < numTabPress; i++) {
await page.keyboard.press('Tab');
}
await page.keyboard.press('Enter');

// Tab to the "Reset Category Grid Demo"
for (let i = 0; i < numTabPress; i++) {
await page.keyboard.press('Tab');
}
await page.keyboard.press('Enter');

// Expect the first tile to be selected after resetting the demo
domInfo = await page.evaluate(() => {
const allTiles = Array.from(
document.querySelectorAll('.product-details-link'),
);
return {
isFocusReset: document.activeElement === allTiles[0],
};
});

expect(domInfo.isFocusReset).toBe(true);
});
});
2 changes: 1 addition & 1 deletion less/load-more.less
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
}

#product-count,
#view-count {
#category-count {
text-align: center;
}

Expand Down
2 changes: 2 additions & 0 deletions sitemap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ https://www.useragentman.com/enable/index.php
https://www.useragentman.com/enable/accessible-text-svg.php
https://www.useragentman.com/enable/alert.php
https://www.useragentman.com/enable/animated-gif-with-pause-button.php
https://www.useragentman.com/enable/audio-player.php
https://www.useragentman.com/enable/button.php
https://www.useragentman.com/enable/carousel.php
https://www.useragentman.com/enable/checkbox.php
Expand All @@ -20,6 +21,7 @@ https://www.useragentman.com/enable/infographic.php
https://www.useragentman.com/enable/input-mask.php
https://www.useragentman.com/enable/link.php
https://www.useragentman.com/enable/listbox.php
https://www.useragentman.com/enable/load-more.php
https://www.useragentman.com/enable/log.php
https://www.useragentman.com/enable/marquee.php
https://www.useragentman.com/enable/meter.php
Expand Down
2 changes: 1 addition & 1 deletion templates/data/meta-info.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"isNPM": "true"
},
"load-more.php": {
"title": "Load More Buttons for Pagination",
"title": "Accessilble Load More Buttons",
"desc": "How to approach pagination using load more buttons."
},
"log.php": {
Expand Down

0 comments on commit 3973288

Please sign in to comment.