Skip to content

Commit

Permalink
Support relative links (#45)
Browse files Browse the repository at this point in the history
* Support relative links

* Update tests

* dep

* fix
  • Loading branch information
NullVoxPopuli authored Nov 7, 2024
1 parent ad918c8 commit cb9b611
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
15 changes: 13 additions & 2 deletions test-app/tests/acceptance/visit-all-links-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@ import { visitAllLinks } from '@universal-ember/test-support';
module('All Links', function (hooks) {
setupApplicationTest(hooks);

test('are visitable without error', async function () {
await visitAllLinks();
test('are visitable without error', async function (assert) {
const size1 = await visitAllLinks();
const size2 = await visitAllLinks((url) => {
assert.ok(url);
});

assert.ok(size1 > 0, 'The test app has links');
assert.ok(size2 > 0, 'The test app has links');
assert.strictEqual(
size1,
size2,
`multiple usages does not visit different numbers of links (${size1} === ${size2})`,
);
});
});
1 change: 0 additions & 1 deletion test-app/tests/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link rel="stylesheet" href="{{rootURL}}assets/test-app.css">
<link rel="stylesheet" href="{{rootURL}}assets/test-support.css">

{{content-for "head-footer"}}
{{content-for "test-head-footer"}}
Expand Down
57 changes: 41 additions & 16 deletions test-support/src/routing/visit-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,34 @@ import QUnit from 'qunit';
import type Owner from '@ember/owner';
import type RouterService from '@ember/routing/router-service';

function findInAppLinks(): string[] {
return (findAll('a')
?.map((link) => link.getAttribute('href'))
?.filter((href) => !href?.startsWith('http'))
.filter(Boolean) || []) as string[];
interface InAppLink {
href: string;
original: string;
selector: string;
}

function findInAppLinks(): InAppLink[] {
const results: InAppLink[] = [];

const allAnchorsOnThePage = findAll('a');

for (const a of allAnchorsOnThePage) {
const href = a.getAttribute('href');

if (!href) continue;
if (href.startsWith('http')) continue;

const url = new URL(href, window.location.href);
const withoutDomain = `${url.pathname}${url.search}${url.hash}`;

results.push({
href: withoutDomain,
original: href,
selector: `a[href="${href}"]`,
});
}

return results;
}

const assert = QUnit.assert;
Expand All @@ -32,7 +55,7 @@ export async function visitAllLinks(
await visit(returnTo);

const inAppLinks = findInAppLinks();
const queue: (string | { changeReturnTo: string })[] = [...inAppLinks];
const queue: (InAppLink | { changeReturnTo: string })[] = [...inAppLinks];

const ctx = getContext() as unknown as { owner: Owner };
const router = ctx?.owner?.lookup('service:router') as RouterService;
Expand All @@ -44,19 +67,19 @@ export async function visitAllLinks(

debugAssert(`Queue entries cannot be falsey`, toVisit);

if (typeof toVisit === 'object' && toVisit !== null) {
if ('changeReturnTo' in toVisit) {
returnTo = toVisit.changeReturnTo;
continue;
}

// In-page links are on the page we're already on.
// As long as we haven't already encountered an error,
// this is silly to check.
if (toVisit.startsWith('#')) {
if (toVisit.original.startsWith('#')) {
continue;
}

const [nonHashPart] = toVisit.split('#');
const [nonHashPart] = toVisit.href.split('#');

// This was our first page, we've already been here
if (nonHashPart === '/') {
Expand All @@ -67,36 +90,38 @@ export async function visitAllLinks(

if (visited.has(key)) continue;

const result = router.recognize(toVisit);
const result = router.recognize(toVisit.href);

if (!result) {
assert.ok(
true,
`${toVisit} on page ${returnTo} is not recognized by this app and will be skipped`,
`${toVisit.href} on page ${returnTo} is not recognized by this app and will be skipped`,
);
continue;
}

await visit(returnTo);

const link = find(`a[href="${toVisit}"]`);
const link = find(toVisit.selector);

debugAssert(`link exists with ${toVisit}`, link);
debugAssert(`link exists via selector \`${toVisit.selector}\``, link);

await click(link);
assert.ok(
currentURL().startsWith(toVisit),
`Navigation was successful: to:${toVisit}, from:${returnTo}`,
currentURL().startsWith(toVisit.href),
`Navigation was successful: to:${toVisit.original}, from:${returnTo}`,
);
visited.add(key);

if (callback) {
await callback(toVisit);
await callback(toVisit.href);
}

const links = findInAppLinks();

queue.push({ changeReturnTo: currentURL() });
queue.push(...links);
}

return visited.size;
}

0 comments on commit cb9b611

Please sign in to comment.