En raison des besoins du projet, des captures d'écran des éléments de la page Web sont requises pendant les tests pour garantir qu'elles semblent normales. AvantJ'ai écrit un article présentant une méthode, utilisez d'abord WebDriver pour prendre une capture d'écran en plein écran, puis recadrez la capture d'écran en fonction de l'emplacement de l'élément cible (élément DOM), en conservant l'emplacement dont nous avons besoin.
Ce code fonctionnait bien jusqu'à ce que je trouve quelque chose : iframe. Le contenu d'une iframe (le frame ordinaire est le même, mais le frame est moins courant maintenant, seul l'iframe est utilisé comme exemple ici) est considéré comme une page Web indépendante, et même l'objet Window est séparé de sa page Web parent. La méthode WebElement.getLocation() dans WebDriver ne peut renvoyer que la relation de position entre ce WebElement et la fenêtre dans laquelle il se trouve. Il n'y a aucun problème avec son implémentation, mais la capture d'écran plein écran contient non seulement le contenu de l'iframe, mais peut également inclure le contenu de sa page parent Contenu, vous devez connaître la position de l'élément cible dans la capture d'écran lors du recadrage. La question est donc de savoir quelle entreprise possède la meilleure technologie d’excavatrice ? Comment calculer la position d'un élément par rapport à la capture d'écran ?
Ce problème doit être abordé dans une catégorie distincte. La raison est la suivante : le comportement des captures d'écran dans Chrome et Firefox est différent. La capture d'écran de Chrome correspond au contenu de la page Web (fenêtre d'affichage) actuellement visible. Par exemple, lorsque la taille réelle de la page Web dépasse la taille de la fenêtre Chrome, le contenu affiché dans la fenêtre est différent en fonction de la position de la barre de défilement. le contenu affiché. Nous devons donc calculer la position de l'élément cible par rapport au contenu actuellement visible. Firefox utilise une méthode capable de capturer le contenu de l'intégralité de la page Web, quelle que soit la taille actuelle de la fenêtre. Donc pour Firefox nous devons calculer la position absolue de l'élément (Absolute Position).
Pour obtenir la position d'un élément, vous devez utiliser une méthode : Element.getBoundingClientRect(). Cette méthode renvoie la position de cet élément par rapport au contenu actuellement visible de la fenêtre dans laquelle il se trouve, représenté par quatre valeurs : haut, gauche, droite et bas. Nous ne nous soucions que du haut et de la gauche. Quant à la taille de découpage, nous pouvons l'obtenir à partir de la longueur et de la largeur de l'élément lui-même, sans calcul. Pour calculer la position de l'élément cible par rapport à la fenêtre de niveau supérieur, il suffit d'ajouter successivement le haut et la gauche de sa fenêtre parent. Le code est le suivant :
function calcViewportLocation(element) { var currentWindow = window; var rect = element.getBoundingClientRect(); // 元素的位置 var top = rect.top; var left = rect.left; while (currentWindow.frameElement != null) { // 处理父级 Window element = currentWindow.frameElement; currentWindow = currentWindow.parent; rect = element.getBoundingClientRect(); if (rect.top > 0) { top += rect.top; } if (rect.left > 0) { left += rect.left; } } return [Math.round(top), Math.round(left)]; }
Le code ci-dessus fonctionne pour Chrome, mais dans Firefox, nous devons également calculer la position absolue de l'élément. Window.pageXOffset est nécessaire ici. pageXOffset, ou scrollX, représente la position de défilement de la barre de défilement horizontale de la fenêtre actuelle. Ajoutez cette valeur en haut à gauche pour obtenir la position horizontale absolue de l'élément cible. Bien entendu, l'iframe peut également être traitée spécialement :
function calcAbsolutLocation(element) { var top = 0; var left = 0; var currentWindow = window; while (element != null) { rect = element.getBoundingClientRect(); var pageYOffset = currentWindow.pageYOffset; var pageXOffset = currentWindow.pageXOffset; if (typeof pageYOffset === 'undefined') { // IE8 currentDocument = currentWindow.document; var bodyElement = (currentDocument.documentElement || currentDocument.body.parentNode || currentDocument.body); pageYOffset = bodyElement.scrollTop; pageXOffset = bodyElement.scrollLeft; } top += rect.top + pageYOffset; left += rect.left + pageXOffset; element = currentWindow.frameElement; currentWindow = currentWindow.parent; if (element != null) { style = window.getComputedStyle(element); top += parseInt(style.borderTopWidth, 10); left += parseInt(style.borderLeftWidth, 10); } } return [Math.round(top), Math.round(left)]; }
Étant donné qu'IE8 ne prend pas en charge pageXOffset et scrollX, un traitement spécial est requis dans IE8, c'est-à-dire la partie marquée "IE8" dans le code. En remplaçant ces deux morceaux de code Javascript par WebElement.getLocation() dans l'article précédent, vous pouvez prendre une capture d'écran d'un élément spécifique dans une iframe.