azon_seeker/scripts/test-amazon-search-parser.ts

105 lines
4.4 KiB
TypeScript

import assert from 'node:assert/strict';
import { JSDOM } from 'jsdom';
import { collectAmazonSearchPageData } from '../src/page-worker/web-injectors/amazon-search-parser';
const html = `
<main id="search">
<section data-component-type="sponsored-brand">
<span aria-label="Sponsored">Sponsored</span>
<article data-asin="B000000001">
<h3>Brand product one</h3>
<a href="/dp/B000000001"><img src="https://example.com/brand-1.jpg" /></a>
</article>
<article data-asin="B000000002">
<h3>Brand product two</h3>
<a href="/dp/B000000002"><img src="https://example.com/brand-2.jpg" /></a>
</article>
</section>
<div class="s-main-slot">
<div class="ordinary-result-grid">
<article data-component-type="s-search-result" data-asin="B000000003">
<span>Amazon's Choice</span>
<h2>Organic product</h2>
<a href="/dp/B000000003"><img class="s-image" src="https://example.com/organic.jpg" /></a>
<span class="a-price"><span class="a-offscreen">$29.99</span></span>
</article>
<article data-component-type="s-search-result" data-asin="B000000004">
<a aria-label="View Sponsored information or leave ad feedback"></a>
<h2>Sponsored product</h2>
<a href="/sspa/click?url=%2Fdp%2FB000000004"><img class="s-image" src="https://example.com/sp.jpg" /></a>
<span class="a-price"><span class="a-offscreen">$33.93</span></span>
<span class="a-price a-text-price" data-a-strike="true"><span class="a-offscreen">$39.99</span></span>
<span class="a-price a-text-price apex-priceperunit-value"><span class="a-offscreen">$0.28</span></span>
</article>
<article data-component-type="s-search-result" data-asin="B000000007">
<h2>Second organic product</h2>
<a href="/dp/B000000007"><img class="s-image" src="https://example.com/organic-2.jpg" /></a>
</article>
</div>
<section class="custom-sponsored-module">
<span>Sponsored</span>
<article data-asin="B000000005">
<h3>Unknown sponsored product</h3>
<a href="/dp/B000000005"><img src="https://example.com/unknown.jpg" /></a>
</article>
</section>
</div>
<aside id="rightResultsATF" data-component-type="sponsored-display">
<span>Sponsored</span>
<article data-asin="B000000006">
<h3>Display product</h3>
<a href="/dp/B000000006"><img src="https://example.com/display.jpg" /></a>
</article>
</aside>
</main>
`;
const dom = new JSDOM(html, { url: 'https://www.amazon.com/s?k=mirror' });
Object.assign(globalThis, {
document: dom.window.document,
Node: dom.window.Node,
Element: dom.window.Element,
HTMLElement: dom.window.HTMLElement,
HTMLAnchorElement: dom.window.HTMLAnchorElement,
HTMLImageElement: dom.window.HTMLImageElement,
});
async function main() {
const items = await collectAmazonSearchPageData({ pattern: 'pattern-2' });
assert.equal(items.length, 7);
const byAsin = new Map(items.map((item) => [item.asin, item]));
assert.equal(byAsin.get('B000000003')?.adType, 'organic');
assert.equal(byAsin.get('B000000004')?.adType, 'sponsoredProducts');
assert.equal(byAsin.get('B000000004')?.price, '$33.93');
assert.equal(byAsin.get('B000000004')?.strikethroughPrice, '$39.99');
assert.equal(byAsin.get('B000000004')?.link, 'https://www.amazon.com/dp/B000000004');
assert.equal(byAsin.get('B000000004')?.placement, 'middleOfSearch');
assert.equal(byAsin.get('B000000001')?.adType, 'sponsoredBrands');
assert.equal(byAsin.get('B000000002')?.adType, 'sponsoredBrands');
assert.equal(byAsin.get('B000000001')?.placement, 'topOfSearch');
assert.equal(byAsin.get('B000000001')?.placementId, byAsin.get('B000000002')?.placementId);
assert.equal(byAsin.get('B000000001')?.adProductIndex, 1);
assert.equal(byAsin.get('B000000002')?.adProductIndex, 2);
assert.equal(byAsin.get('B000000005')?.adType, 'unknownSponsored');
assert.equal(byAsin.get('B000000005')?.placement, 'bottomOfSearch');
assert.equal(byAsin.get('B000000006')?.adType, 'sponsoredDisplay');
assert.equal(byAsin.get('B000000006')?.placement, 'sidebar');
assert.deepEqual(
items.map((item) => item.pageRank),
[1, 2, 3, 4, 5, 6, 7],
);
console.log('Amazon search parser fixtures passed.');
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});