also looking at this
fix: support structured DOM selectors
#847
6 files
+225
-57
| @@ -117,6 +117,30 @@ describe('Web Scraper - Static HTML Parsing', () => { | ||
| 117 | 117 | expect(doc.querySelector('ytd-display-ad-renderer')?.textContent).toContain('Ad') |
| 118 | 118 | expect(doc.querySelector('[data-ad-slot]')?.tagName).toBe('ytd-display-ad-renderer') |
| 119 | 119 | }) |
| 120 | ||
| 121 | it('should follow descendant and child combinators for table rows', () => { | |
| 122 | const doc = parseHTML(` | |
| 123 | <table class="items"> | |
| 124 | <tbody> | |
| 125 | <tr class="odd"><td><a href="/club/startseite/verein/31">Club</a></td></tr> | |
| 126 | <tr class="even"><td><a href="/club/startseite/verein/42">Other</a></td></tr> | |
| 127 | </tbody> | |
| 128 | </table> | |
| 129 | `) | |
| 130 | ||
| 131 | expect(doc.querySelectorAll('table.items > tbody > tr')).toHaveLength(2) | |
| 132 | expect(doc.querySelectorAll('table.items a[href*="/verein/"]')).toHaveLength(2) | |
| 133 | expect(doc.querySelector('tr.odd > td > a')?.getAttribute('href')).toContain('/verein/31') | |
| 134 | }) | |
| 135 | ||
| 136 | it('should decode entities in text and attributes', () => { | |
| 137 | const doc = parseHTML('<a title="Brighton & Hove Albion">Brighton & Hove Albion €1.2bn</a>') | |
| 138 | const link = doc.querySelector('a') | |
| 139 | ||
| 140 | expect(link?.getAttribute('title')).toBe('Brighton & Hove Albion') | |
| 141 | expect(link?.textContent).toBe('Brighton & Hove\u00A0Albion €1.2bn') | |
| 142 | expect(extractText('<span>one</span><span>two</span>')).toBe('one two') | |
| 143 | }) | |
| 120 | 144 | }) |
| 121 | 145 | |
| 122 | 146 | describe('Client-Side Scraper - Detection', () => { |