expect(attrs.attribs).toHaveProperty('disabled', ''); }); it(`should handle comments: ${comment}`, () => { const elem = parse(comment, defaultOpts, false, null).children[0]; expect(elem.type).toBe('comment'); expect(elem).toHaveProperty('data', ' sexy '); }); it(`should handle conditional comments: ${conditional}`, () => { const elem = parse(conditional, defaultOpts, false, null).children[0]; expect(elem.type).toBe('comment'); expect(elem).toHaveProperty( 'data', conditional.replace('', ''), ); }); it(`should handle text: ${text}`, () => { const text_ = parse(text, defaultOpts, false, null).children[0]; expect(text_.type).toBe('text'); expect(text_).toHaveProperty('data', 'lorem ipsum'); }); it(`should handle script tags: ${script}`, () => { const script_ = parse(script, defaultOpts, false, null) .children[0] as Element; expect(script_.type).toBe('script'); expect(script_.tagName).toBe('script'); expect(script_.attribs).toHaveProperty('type', 'text/javascript'); expect(script_.childNodes).toHaveLength(1); expect(script_.childNodes[0].type).toBe('text'); expect(script_.childNodes[0]).toHaveProperty( 'data', 'alert("hi world!");', ); }); it(`should handle style tags: ${style}`, () => { const style_ = parse(style, defaultOpts, false, null) .children[0] as Element; expect(style_.type).toBe('style'); expect(style_.tagName).toBe('style'); expect(style_.attribs).toHaveProperty('type', 'text/css'); expect(style_.childNodes).toHaveLength(1); expect(style_.childNodes[0].type).toBe('text'); expect(style_.childNodes[0]).toHaveProperty( 'data', ' h2 { color:blue; } ', ); }); it(`should handle directives: ${directive}`, () => { const elem = parse(directive, defaultOpts, true, null).children[0]; expect(elem.type).toBe('directive'); expect(elem).toHaveProperty('data', '!DOCTYPE html'); expect(elem).toHaveProperty('name', '!doctype'); }); }); describe('.parse', () => { // Root test utility it(`should add root to: ${basic}`, () => { const root = parse(basic, defaultOpts, true, null); rootTest(root); expect(root.childNodes).toHaveLength(1); expect(root.childNodes[0]).toHaveProperty('tagName', 'html'); }); it(`should add root to: ${siblings}`, () => { const root = parse(siblings, defaultOpts, false, null); rootTest(root); expect(root.childNodes).toHaveLength(2); expect(root.childNodes[0]).toHaveProperty('tagName', 'h2'); expect(root.childNodes[1]).toHaveProperty('tagName', 'p'); expect(root.childNodes[1].parent).toBe(root); }); it(`should add root to: ${comment}`, () => { const root = parse(comment, defaultOpts, false, null); rootTest(root); expect(root.childNodes).toHaveLength(1); expect(root.childNodes[0].type).toBe('comment'); }); it(`should add root to: ${text}`, () => { const root = parse(text, defaultOpts, false, null); rootTest(root); expect(root.childNodes).toHaveLength(1); expect(root.childNodes[0].type).toBe('text'); }); it(`should add root to: ${scriptEmpty}`, () => { const root = parse(scriptEmpty, defaultOpts, false, null); rootTest(root); expect(root.childNodes).toHaveLength(1); expect(root.childNodes[0].type).toBe('script'); }); it(`should add root to: ${styleEmpty}`, () => { const root = parse(styleEmpty, defaultOpts, false, null); rootTest(root); expect(root.childNodes).toHaveLength(1); expect(root.childNodes[0].type).toBe('style'); }); it(`should add root to: ${directive}`, () => { const root = parse(directive, defaultOpts, true, null); rootTest(root); expect(root.childNodes).toHaveLength(2); expect(root.childNodes[0].type).toBe('directive'); }); it('should simply return root', () => { const oldroot = parse(basic, defaultOpts, true, null); const root = parse(oldroot, defaultOpts, true, null); expect(root).toBe(oldroot); rootTest(root); expect(root.childNodes).toHaveLength(1); expect(root.childNodes[0]).toHaveProperty('tagName', 'html'); }); it('should expose the DOM level 1 API', () => { const root = parse( '

', defaultOpts, false, null, ).childNodes[0] as Element; const childNodes = root.childNodes as Element[]; expect(childNodes).toHaveLength(3); expect(root.tagName).toBe('div'); expect(root.firstChild).toBe(childNodes[0]); expect(root.lastChild).toBe(childNodes[2]); expect(childNodes[0].tagName).toBe('a'); expect(childNodes[0].previousSibling).toBe(null); expect(childNodes[0].nextSibling).toBe(childNodes[1]); expect(childNodes[0].parentNode).toBe(root); expect((childNodes[0] as Element).childNodes).toHaveLength(0); expect(childNodes[0].firstChild).toBe(null); expect(childNodes[0].lastChild).toBe(null); expect(childNodes[1].tagName).toBe('span'); expect(childNodes[1].previousSibling).toBe(childNodes[0]); expect(childNodes[1].nextSibling).toBe(childNodes[2]); expect(childNodes[1].parentNode).toBe(root); expect(childNodes[1].childNodes).toHaveLength(0); expect(childNodes[1].firstChild).toBe(null); expect(childNodes[1].lastChild).toBe(null); expect(childNodes[2].tagName).toBe('p'); expect(childNodes[2].previousSibling).toBe(childNodes[1]); expect(childNodes[2].nextSibling).toBe(null); expect(childNodes[2].parentNode).toBe(root); expect(childNodes[2].childNodes).toHaveLength(0); expect(childNodes[2].firstChild).toBe(null); expect(childNodes[2].lastChild).toBe(null); }); it('Should parse less than or equal sign sign', () => { const root = parse('A<=B', defaultOpts, false, null); const { childNodes } = root; expect(childNodes[0]).toHaveProperty('tagName', 'i'); expect((childNodes[0] as Element).childNodes[0]).toHaveProperty( 'data', 'A', ); expect(childNodes[1]).toHaveProperty('data', '<='); expect(childNodes[2]).toHaveProperty('tagName', 'i'); expect((childNodes[2] as Element).childNodes[0]).toHaveProperty( 'data', 'B', ); }); it('Should ignore unclosed CDATA', () => { const root = parse( '', defaultOpts, false, null, ); const childNodes = root.childNodes as Element[]; expect(childNodes[0].tagName).toBe('a'); expect(childNodes[1].tagName).toBe('script'); expect(childNodes[1].childNodes[0]).toHaveProperty( 'data', 'foo // to documents', () => { const root = parse('', defaultOpts, true, null); const childNodes = root.childNodes as Element[]; expect(childNodes[0].tagName).toBe('html'); expect(childNodes[0].childNodes[0]).toHaveProperty('tagName', 'head'); }); it('Should implicitly create around ', () => { const root = parse( '
bar
', defaultOpts, false, null, ); const childNodes = root.childNodes as Element[]; expect(childNodes[0].tagName).toBe('table'); expect(childNodes[0].childNodes.length).toBe(1); expect(childNodes[0].childNodes[0]).toHaveProperty('tagName', 'tbody'); expect((childNodes[0] as any).childNodes[0].childNodes[0]).toHaveProperty( 'tagName', 'tr', ); expect( (childNodes[0] as any).childNodes[0].childNodes[0].childNodes[0] .tagName, ).toBe('td'); expect( (childNodes[0] as any).childNodes[0].childNodes[0].childNodes[0] .childNodes[0].data, ).toBe('bar'); }); it('Should parse custom tag ', () => { const root = parse('test', defaultOpts, false, null); const childNodes = root.childNodes as Element[]; expect(childNodes.length).toBe(1); expect(childNodes[0].tagName).toBe('line'); expect(childNodes[0].childNodes[0]).toHaveProperty('data', 'test'); }); it('Should properly parse misnested table tags', () => { const root = parse( 'i1i2i3', defaultOpts, false, null, ); const childNodes = root.childNodes as Element[]; expect(childNodes.length).toBe(3); for (let i = 0; i < childNodes.length; i++) { const child = childNodes[i]; expect(child.tagName).toBe('tr'); expect(child.childNodes[0]).toHaveProperty('tagName', 'td'); expect((child.childNodes[0] as Element).childNodes[0]).toHaveProperty( 'data', `i${i + 1}`, ); } }); it('Should correctly parse data url attributes', () => { const html = '
'; const expectedAttr = 'font-family:"butcherman-caps"; src:url(data:font/opentype;base64,AAEA...);'; const root = parse(html, defaultOpts, false, null); const childNodes = root.childNodes as Element[]; expect(childNodes[0].attribs).toHaveProperty('style', expectedAttr); }); it('Should treat tag content as text', () => { const root = parse('<xmp><h2>', defaultOpts, false, null); const childNodes = root.childNodes as Element[]; expect(childNodes[0].childNodes[0]).toHaveProperty('data', '

'); }); it('Should correctly parse malformed numbered entities', () => { const root = parse('

z&#

', defaultOpts, false, null); const childNodes = root.childNodes as Element[]; expect(childNodes[0].childNodes[0]).toHaveProperty('data', 'z&#'); }); it('Should correctly parse mismatched headings', () => { const root = parse('

Test

', defaultOpts, false, null); const { childNodes } = root; expect(childNodes.length).toBe(2); expect(childNodes[0]).toHaveProperty('tagName', 'h2'); expect(childNodes[1]).toHaveProperty('tagName', 'div'); }); it('Should correctly parse tricky
 content', () => {
      const root = parse(
        '
\nA <- factor(A, levels = c("c","a","b"))\n
', defaultOpts, false, null, ); const childNodes = root.childNodes as Element[]; expect(childNodes.length).toBe(1); expect(childNodes[0].tagName).toBe('pre'); expect(childNodes[0].childNodes[0]).toHaveProperty( 'data', 'A <- factor(A, levels = c("c","a","b"))\n', ); }); it('should pass the options for including the location info to parse5', () => { const root = parse( '

Hello

', { ...defaultOpts, sourceCodeLocationInfo: true }, false, null, ); const location = root.children[0].sourceCodeLocation; expect(typeof location).toBe('object'); expect(location?.endOffset).toBe(12); }); }); });