diff --git a/src/browser/vdiff.js b/src/browser/vdiff.js index 14790052..e4f469cc 100644 --- a/src/browser/vdiff.js +++ b/src/browser/vdiff.js @@ -19,11 +19,29 @@ mocha.setup({ }); /* eslint-enable */ -function findTarget(elem) { - if (!elem.shadowRoot) return elem; - const nestedTarget = elem.shadowRoot.querySelector('.vdiff-target'); - if (!nestedTarget) return elem; - return findTarget(nestedTarget); +function findTargets(elem) { + if (!elem.shadowRoot) return [elem]; + const nestedTargets = elem.shadowRoot.querySelectorAll('.vdiff-target'); + if (nestedTargets.length === 0) return [elem]; + return Array.from(nestedTargets).reduce((acc, target) => [...acc, ...findTargets(target)], []); +} + +function findLargestRect(elems) { + let largestRect = { left: Number.MAX_SAFE_INTEGER, top: Number.MAX_SAFE_INTEGER, right: 0, bottom: 0 }; + elems.forEach(elem => { + const targets = findTargets(elem); + targets.forEach(target => { + const targetRect = target.getBoundingClientRect(); + largestRect = { + left: Math.floor(Math.min(largestRect.left, targetRect.left)), + top: Math.floor(Math.min(largestRect.top, targetRect.top)), + right: Math.ceil(Math.max(largestRect.right, targetRect.right)), + bottom: Math.ceil(Math.max(largestRect.bottom, targetRect.bottom)) + }; + }); + }); + + return { x: largestRect.left, y: largestRect.top, width: largestRect.right - largestRect.left, height: largestRect.bottom - largestRect.top }; } async function ScreenshotAndCompare(opts) { @@ -36,8 +54,8 @@ async function ScreenshotAndCompare(opts) { const name = this.test.fullTitle(); let rect = null; if (this.elem !== document) { - const target = findTarget(this.elem); - rect = target.getBoundingClientRect(); + const elemsToInclude = [this.elem, ...this.elem.querySelectorAll('.vdiff-include')]; + rect = findLargestRect(elemsToInclude); } const slowDuration = this.test.slow(); let result = await executeServerCommand('brightspace-visual-diff-compare', { name, rect, slowDuration, opts }); diff --git a/test/browser/element.vdiff.js b/test/browser/element.vdiff.js index 12cb9f49..bf8b3f6f 100644 --- a/test/browser/element.vdiff.js +++ b/test/browser/element.vdiff.js @@ -1,4 +1,4 @@ -import { css, html, LitElement } from 'lit'; +import { css, html, LitElement, nothing } from 'lit'; import { defineCE, expect, fixture, hoverElem } from '../../src/browser/index.js'; import { executeServerCommand } from '@web/test-runner-commands'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; @@ -40,8 +40,30 @@ const elementTag = defineCE( } ); +const absoluteElementTag = defineCE( + class extends LitElement { + static get styles() { + return css` + div { + border: 1px solid blue; + position: absolute; + bottom: 250px; + } + `; + } + render() { + return html` +
Absolutely Positioned
+ `; + } + } +); + const fixedElementTag = defineCE( class extends LitElement { + static get properties() { + return { multipleTargets: { type: Boolean, attribute: 'multiple-targets' } }; + } static get styles() { return css` div { @@ -59,6 +81,9 @@ const fixedElementTag = defineCE(
+ ${this.multipleTargets ? unsafeHTML(` + <${absoluteElementTag} class="vdiff-target"> + `) : nothing} `; } } @@ -69,6 +94,7 @@ const nestedElementTag = defineCE( render() { return html`${unsafeHTML(` <${fixedElementTag} class="vdiff-target"><${elementTag} text="Visual Difference"> + `)}`; } } @@ -103,6 +129,16 @@ describe('element-matches', () => { const elem = await fixture(`<${nestedElementTag}>`, { viewport: { width: 500, height: 500 } }); await expect(elem).to.be.golden(); }); + + it('multiple targets', async() => { + const elem = await fixture(`<${fixedElementTag} multiple-targets><${elementTag} text="Visual Difference">`, { viewport: { width: 500, height: 500 } }); + await expect(elem).to.be.golden(); + }); + + it('multiple to include', async() => { + const elem = await fixture(`<${nestedElementTag}><${absoluteElementTag} class="vdiff-include">`, { viewport: { width: 500, height: 500 } }); + await expect(elem).to.be.golden(); + }); }); describe('element-different', () => { diff --git a/test/browser/golden/element-matches/chromium/multiple-targets.png b/test/browser/golden/element-matches/chromium/multiple-targets.png new file mode 100644 index 00000000..06b4810f Binary files /dev/null and b/test/browser/golden/element-matches/chromium/multiple-targets.png differ diff --git a/test/browser/golden/element-matches/chromium/multiple-to-include.png b/test/browser/golden/element-matches/chromium/multiple-to-include.png new file mode 100644 index 00000000..06b4810f Binary files /dev/null and b/test/browser/golden/element-matches/chromium/multiple-to-include.png differ diff --git a/test/browser/nested/golden/element-matches/chromium/multiple-targets.png b/test/browser/nested/golden/element-matches/chromium/multiple-targets.png new file mode 100644 index 00000000..06b4810f Binary files /dev/null and b/test/browser/nested/golden/element-matches/chromium/multiple-targets.png differ diff --git a/test/browser/nested/golden/element-matches/chromium/multiple-to-include.png b/test/browser/nested/golden/element-matches/chromium/multiple-to-include.png new file mode 100644 index 00000000..06b4810f Binary files /dev/null and b/test/browser/nested/golden/element-matches/chromium/multiple-to-include.png differ