例如,我有这个:
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
这:
<div style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">mars</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
我希望第二个看起来像第一个。
我相信它们看起来是相同的,但是我唯一的证明是使用了旧的“在Windows真正的快捷方式和眼球之间来回切换”技术。 (天文学家称其为“闪烁比较器”-https://en.wikipedia.org/wiki/Blink_comparator)。我确保窗户的大小相同,位置相同。但是,如果渲染的HTML无法在屏幕上显示,则可能太困难了。
是否有更确定的工具或方法来进行这种比较?
我在Chrome 77.0.3865.120和Firefox 69.0.3中都查看了这些内容。
例如,我知道使用浏览器酸性测试(最初是Web Standards Project的一部分)https://www.acidtests.org/-像素完美渲染是基准。
(额外的功劳:第二个代码段的HTML可能足以满足我的需求;如果您愿意提出改进建议,将是值得欢迎的。)
编辑:我的问题比较了两个小的HTML示例,这些示例可以呈现为适合浏览器的可见部分。但总的来说,我想知道HTML的答案可能会很长。
答案 0 :(得分:8)
开发CSS related webiste时,我做过类似的事情。我必须将HTML / CSS生成的输出与以前使用HTML / CSS生成的图像进行比较。
我使用了dom-to-image,它将代码转换为base64编码的图像。我将此图像放在画布中,然后使用pixelmatch在两个图像之间进行比较。
这里是一个例子来说明:
var node1 = document.querySelector("pre");
var node2 = document.querySelector(".div");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
/* Change both code to Image and put inside Canvas */
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
/* Run the pixel matching*/
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, 300, 300).data;
var im_o = ctx2.getImageData(0, 0, 300, 300).data;
var pixDiff = pixelmatch(im_r, im_o, false, 280, 280, {
threshold: 0.1
});
console.log(pixDiff);
}, 3000);
canvas {
border: 1px solid;
}
pre,
.div {
border: 2px solid red;
width: 300px;
height: 300px;
box-sizing: border-box;
margin: 0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
<div class="div" style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">mars</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
<canvas width="300" height="300" class="first"></canvas>
<canvas width="300" height="300" class="second"></canvas>
在上面的代码中,我们有2个HTML块和2个画布,在其中绘制我们的块。如您所见,JS非常简单。最后的代码运行像素匹配,并显示两个画布有多少个不同的像素。我添加了一个延迟,以确保加载两个图像(您可以稍后通过一些事件进行优化)
您还可以考虑使用第三个画布来突出显示两个图像之间的差异并获得视觉差异:
var node1 = document.querySelector("pre");
var node2 = document.querySelector(".div");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
/* Change both code to Image and put inside Canvas */
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
/* Run the pixel matching*/
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, 300, 300).data;
var im_o = ctx2.getImageData(0, 0, 300, 300).data;
var diff = ctx3.createImageData(300, 300);
var pixDiff = pixelmatch(im_r, im_o, diff.data, 300, 300, {
threshold: 0.1
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
canvas {
border: 1px solid;
}
pre,
.div {
border: 2px solid red;
width: 300px;
height: 300px;
box-sizing: border-box;
margin: 0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
<div class="div" style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">mars</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
<canvas width="300" height="300" class="first"></canvas>
<canvas width="300" height="300" class="second"></canvas>
<canvas width="300" height="300" class="result"></canvas>
让我们更改内容以了解一些区别:
var node1 = document.querySelector("pre");
var node2 = document.querySelector(".div");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
/* Change both code to Image and put inside Canvas */
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
/* Run the pixel matching*/
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, 300, 300).data;
var im_o = ctx2.getImageData(0, 0, 300, 300).data;
var diff = ctx3.createImageData(300, 300);
var pixDiff = pixelmatch(im_r, im_o, diff.data, 300, 300, {
threshold: 0.1
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
canvas {
border: 1px solid;
}
pre,
.div {
border: 2px solid red;
width: 300px;
height: 300px;
box-sizing: border-box;
margin: 0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
<div class="div" style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">april</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
<canvas width="300" height="300" class="first"></canvas>
<canvas width="300" height="300" class="second"></canvas>
<canvas width="300" height="300" class="result"></canvas>
您可以阅读有关我使用的两个插件如何工作的更多信息,并找到更多有趣的选项。
我将尺寸固定为300x300,以使代码段内的演示变得容易,但是您可以考虑使用更大的高度和宽度。
更新
这是一个比较现实的示例,可以在产生相同结果的两个布局之间进行比较。画布的宽度/高度将是动态的,并基于内容。我将只显示具有差异的最后一个画布。
var node1 = document.querySelector(".flex");
var node2 = document.querySelector(".grid");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
canvas1.height= node1.offsetHeight;
canvas2.height= node2.offsetHeight;
canvas3.height= node1.offsetHeight;
canvas1.width= node1.offsetWidth;
canvas2.width= node2.offsetWidth;
canvas3.width= node1.offsetWidth;
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
var im_o = ctx2.getImageData(0, 0, canvas1.width, canvas1.height).data;
var diff = ctx3.createImageData(canvas1.width, canvas1.height);
var pixDiff = pixelmatch(im_r, im_o, diff.data, canvas1.width, canvas1.height, {
threshold: 0.2
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
.grid {
display:grid;
grid-template-columns:repeat(3,minmax(0,1fr));
border:2px solid red;
}
h1 {
text-align:center;
grid-column:1/-1;
flex-basis:100%;
}
.flex {
display:flex;
flex-wrap:wrap;
border:2px solid red;
}
.flex > div {
flex-grow:1;
flex-basis:0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<div class="grid">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/10/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<div class="flex">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/10/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<canvas width="300" height="300" class="first" style="display:none;"></canvas>
<canvas width="300" height="300" class="second" style="display:none;"></canvas>
<canvas width="300" height="300" class="result"></canvas>
让我们使用其他图片:
var node1 = document.querySelector(".flex");
var node2 = document.querySelector(".grid");
var canvas1 = document.querySelector(".first");
var canvas2 = document.querySelector(".second");
var canvas3 = document.querySelector(".result");
canvas1.height= node1.offsetHeight;
canvas2.height= node2.offsetHeight;
canvas3.height= node1.offsetHeight;
canvas1.width= node1.offsetWidth;
canvas2.width= node2.offsetWidth;
canvas3.width= node1.offsetWidth;
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
var ctx3 = canvas3.getContext("2d");
domtoimage.toPng(node1)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx1.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
domtoimage.toPng(node2)
.then(function(dataUrl) {
var image = new Image();
image.onload = function() {
ctx2.drawImage(this, 0, 0);
};
image.src = dataUrl;
})
setTimeout(function() {
var im_r = ctx1.getImageData(0, 0, canvas1.width, canvas1.height).data;
var im_o = ctx2.getImageData(0, 0, canvas1.width, canvas1.height).data;
var diff = ctx3.createImageData(canvas1.width, canvas1.height);
var pixDiff = pixelmatch(im_r, im_o, diff.data, canvas1.width, canvas1.height, {
threshold: 0.2
});
ctx3.putImageData(diff, 0, 0);
console.log(pixDiff);
}, 3000);
.grid {
display:grid;
grid-template-columns:repeat(3,minmax(0,1fr));
border:2px solid red;
}
h1 {
text-align:center;
grid-column:1/-1;
flex-basis:100%;
}
.flex {
display:flex;
flex-wrap:wrap;
border:2px solid red;
}
.flex > div {
flex-grow:1;
flex-basis:0;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/pixel.js"></script>
<div class="grid">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/10/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<div class="flex">
<h1>A title here</h1>
<div>
<img src="https://picsum.photos/id/12/200/200" >
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus aliquam condimentum mollis. Phasellus faucibus diam quis lorem efficitur, id egestas neque malesuada</div>
<div> Maecenas sollicitudin lacinia finibus. Integer vel varius eros. Morbi et ante eget est mollis sollicitudin.</div>
</div>
<canvas width="300" height="300" class="first" style="display:none;"></canvas>
<canvas width="300" height="300" class="second" style="display:none;"></canvas>
<canvas width="300" height="300" class="result"></canvas>
答案 1 :(得分:5)
这里有一个实际上可以对DOM进行度量的想法-我只是将有问题的文本替换为具有可以查询的类的div。然后,您可以打印所有节点的偏移量。
根据我的测量,字符缩进确实与
相同。
var nodes = document.getElementsByClassName('measure');
for (var n of nodes) {
console.log(n.offsetLeft);
}
.measure {
display: inline-block;
background: red;
width: 50px;
height: 5px;
}
<pre>
<div class="measure"></div><br/>
<div class="measure"></div><br/>
<div class="measure"></div><br/>
<div class="measure"></div><br/>
<div class="measure"></div><br/>
<div class="measure"></div><br/>
<div class="measure"></div><br/>
</pre>
var nodes = document.getElementsByClassName('measure');
for (var n of nodes) {
console.log(n.offsetLeft);
}
.measure {
display: inline-block;
background: red;
width: 50px;
height: 5px;
}
<div style="font-family:monospace">
<div style="text-indent: 0"><div class="measure"></div></div> <br/>
<div style="text-indent: 4ch"><div class="measure"></div></div> <br/>
<div style="text-indent: 4ch"><div class="measure"></div></div> <br/>
<div style="text-indent: 8ch"><div class="measure"></div></div> <br/>
<div style="text-indent: 8ch"><div class="measure"></div></div> <br/>
<div style="text-indent: 12ch"><div class="measure"></div></div> <br/>
<div style="text-indent: 4ch"><div class="measure"></div></div> <br/>
</div>
答案 2 :(得分:3)
打印两页的屏幕并比较像素。
您可以使用像selenium这样的网络驱动程序,在图像文件(png,jpg等)中渲染两个屏幕-selenium具有执行此操作的方法-并编写了一个软件来读取两个像素以进行相似性比较。
Webdriver是可以用代码控制的浏览器。而且,您可以找到可在网络上比较图像的软件。
您可以在此链接中找到更多信息:https://selenium.dev/
答案 3 :(得分:2)
使用键盘上的“打印屏幕”按钮(或其他屏幕截图工具)。
对于要长或宽以适合屏幕显示的页面,请为每个页面拍摄多个屏幕截图,然后在照片编辑器中将它们组合在一起。您可以拍摄大页面的重叠屏幕截图,将它们放置在单独的图层上,然后在合并图层以创建整个页面的合成之前,使用重叠的部分精确定位片段。
您可以使用fireshot之类的浏览器扩展程序一次捕获整个页面。
打开photoshop或转到photopea。
将屏幕截图粘贴到图层中。
重复第二页,粘贴到另一个图层中。
切换图层可见性和任何更改都是显而易见的。或调整顶层的不透明度(和/或设置不同的混合模式)以进行比较。
使用诸如pixel-perfect-2之类的浏览器扩展程序,该扩展程序允许在浏览器中覆盖半透明图像。这也是检查对齐和间距的有用扩展,因为您可以在浏览器中用网格图像覆盖页面。
使用图像差异工具。快速的Google搜索将发现太多内容无法在此处列出。有一些图片差异插件,可用于某些代码编辑器,命令行工具,Python脚本和在线服务,例如diffchecker。
答案 4 :(得分:2)
您可以在同一文档中的另一个位置上放置以下位置:absolute; 也许放大以查看更详细。
mainClass in Compile := Some("com.example.MyScalaCodeMain")
#a, #b {
position:absolute;
left:0;
top:0;
margin:0;
padding:0;
color:green;
opacity:0.5;
}
#a {
color:red;
}
#b {
color:green;
}
答案 5 :(得分:2)
使用iframe将两个页面彼此叠加。这应该使您可以看到两个页面之间的任何差异。
main.html:
<iframe src="doc1.html"></iframe>
<iframe src="doc2.html" style="opacity:0.5"></iframe>
<style>
html, body {
margin:0;
height:100%;
}
iframe {
height:100%;
width:100%;
position:absolute;
top:0;
left:0;
}
</style>
doc1.html:
<pre>
sun<br/>
mercury <br/>
venus <br/>
earth <br/>
mars <br/>
jupiter <br/>
saturn <br/>
</pre>
doc2.html
<div style="font-family:monospace">
<div style="text-indent: 0">sun</div> <br/>
<div style="text-indent: 4ch">mercury</div> <br/>
<div style="text-indent: 4ch">venus</div> <br/>
<div style="text-indent: 8ch">earth</div> <br/>
<div style="text-indent: 8ch">mars</div> <br/>
<div style="text-indent: 12ch">jupiter</div> <br/>
<div style="text-indent: 4ch">saturn</div> <br/>
</div>
(我怀疑有一种方法可以使用Stack Snippets来完成。请随时启发我)
答案 6 :(得分:1)
这里有一些非常复杂和聪明的代码方法,所以这里是一个简单的方法,
拍摄一张截图,在支持透明性的图像编辑器(如photoshop)中将其打开
将其粘贴,然后以屏幕炫耀的方式展示CSS并将其粘贴到第二张粘贴的图像中,使其不透明度为50%,然后查看它们是否对齐。
答案 7 :(得分:1)
到目前为止,我几乎没有人提到实际的测试工具。
有很多适合您的用例的工具(通常是较大框架的一部分):
仅列举this列表中的一部分。也许找自己,然后选择一种适合您的环境。
如果您要构建可持续的自动化系统,请不要依赖黑客。它可能只是“质量检查”,但可以在以后的版本中认真保存您的**。