azon_seeker/scripts/test-amazon-review-page.ts
Ktight 90110a48f0
Feat/advertisement (#26)
* feat: add Amazon collection metadata and reliable sync

* fix: route extension sync through configured server

* chore: release extension v0.7.13

* fix: handle extension ports across BFCache navigation

* fix: classify bottom Sponsored Brands video placements

* fix: exclude hidden Amazon ad cards

* fix: derive Amazon result page from URL

* fix: ignore hidden Amazon sponsored products

* fix: preserve base Amazon product collection

* fix: bind Amazon results to visible page

* fix: classify visible Amazon ad formats

* fix: wait for lazy Amazon ad modules

* perf: reduce Amazon lazy-load scroll stops

* fix: classify Amazon sponsored brand and video search ads

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: collect Shop by type thematic SP ads via redirect chains without data-asin

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: classify sponsored ads across new Amazon templates

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: PetrichorFun <127877748+PetrichorFun@users.noreply.github.com>
2026-09-10 18:03:11 +08:00

83 lines
3.1 KiB
TypeScript

import { JSDOM } from 'jsdom';
import {
collectAmazonNextReviewPageUrl,
isAmazonReviewRatingFilterIgnored,
waitForAmazonReviewPageReady,
} from '../src/page-worker/web-injectors/amazon-review-page';
const installDom = (html: string, url = 'https://www.amazon.com/product-reviews/B08XM6S6ZL') => {
const dom = new JSDOM(html, { url });
Object.defineProperty(dom.window.document, 'readyState', {
configurable: true,
value: 'complete',
});
Object.assign(globalThis, { document: dom.window.document, window: dom.window });
Object.assign(dom.window.HTMLElement.prototype, { scrollIntoView: () => undefined });
return dom;
};
const main = async () => {
if (
!isAmazonReviewRatingFilterIgnored(
[{ rating: '5.0 out of 5 stars' }, { rating: '3.0 out of 5 stars' }],
3,
)
) {
throw new Error('Mixed ratings must be detected when Amazon ignores filterByStar');
}
if (
isAmazonReviewRatingFilterIgnored(
[{ rating: '3.0 out of 5 stars' }, { rating: '3.0 out of 5 stars' }],
3,
)
) {
throw new Error('A correctly filtered review page must not be treated as limited');
}
const readyDom = installDom('<div id="cm_cr-review_list"></div>');
await waitForAmazonReviewPageReady({});
readyDom.window.close();
const paginationDom = installDom(
'<div data-hook="pagination-bar"><ul class="a-pagination"><li>Previous</li><li class="a-last"><a href="/product-reviews/B08XM6S6ZL?pageNumber=2">Next</a></li></ul></div>',
);
const nextUrl = await collectAmazonNextReviewPageUrl();
if (nextUrl !== 'https://www.amazon.com/product-reviews/B08XM6S6ZL?pageNumber=2') {
throw new Error(`Unexpected next review URL: ${nextUrl}`);
}
paginationDom.window.close();
const standalonePaginationDom = installDom(
'<div id="cm_cr-review_list"><div id="R1-review-card" data-hook="review"></div></div><ul class="a-pagination"><li>Previous</li><li class="a-last"><a href="/product-reviews/B08XM6S6ZL?pageNumber=3">Next</a></li></ul>',
'https://www.amazon.com/product-reviews/B08XM6S6ZL?pageNumber=2',
);
const standaloneNextUrl = await collectAmazonNextReviewPageUrl();
if (standaloneNextUrl !== 'https://www.amazon.com/product-reviews/B08XM6S6ZL?pageNumber=3') {
throw new Error(`Unexpected standalone review pagination URL: ${standaloneNextUrl}`);
}
standalonePaginationDom.window.close();
const lastPageDom = installDom(
'<div data-hook="pagination-bar"><ul class="a-pagination"><li class="a-last a-disabled">Next</li></ul></div>',
);
if ((await collectAmazonNextReviewPageUrl()) !== null) {
throw new Error('Disabled review pagination must not return a URL');
}
lastPageDom.window.close();
const signInDom = installDom('<main>Sign in</main>', 'https://www.amazon.com/ap/signin');
await waitForAmazonReviewPageReady({}).then(
() => {
throw new Error('Sign-in page should fail immediately');
},
(error) => {
if (!String(error).includes('需要重新登录')) throw error;
},
);
signInDom.window.close();
console.log('Amazon review page tests passed.');
};
void main();