From c50ba1f7c898a34a3660da21ec761c872c489a45 Mon Sep 17 00:00:00 2001 From: Ken Soh Date: Sat, 22 Jun 2019 00:12:32 +0800 Subject: [PATCH] #462 - improve snap step chrome snapshots In newer DevTools Protocol, Page.captureScreenshot now supports clip parameter. This allows directly specifying the region to capture for a web element, instead of the previous implementation where a full screen is captured and then clipped as a PhantomJS webpage. This improves performance as only the data of the selector snapshot is needed to be transferred between TagUI and Chrome instead of the whole webpage. Also, as PhantomJS is not involved, the quality and color would be more accurate without additional web profile of PhantomJS. Lastly, this improvement also fixes an issue with snap step in live mode for Chrome, where the snapshot captures full screen instead of only the selector. --- src/tagui_header.js | 13 ++++++++++++- src/test/positive_test.signature | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/tagui_header.js b/src/tagui_header.js index 999e943b..f410b50d 100644 --- a/src/tagui_header.js +++ b/src/tagui_header.js @@ -576,13 +576,24 @@ else var ws_message = chrome_step('Page.captureScreenshot',{format: format, qual try {var ws_json = JSON.parse(ws_message); screenshot_data = ws_json.result.data;} catch(e) {screenshot_data = '';} var fs = require('fs'); fs.write(filename,chrome.decode(screenshot_data),'wb');}; +/* // backup of previous captureSelector implementation to use Page.captureScreenshot with clipping directly chrome.captureSelector = function(filename,selector) { // capture screenshot of selector to png/jpg/jpeg format // first capture entire screen, then use casperjs / phantomjs browser to crop image base on selector dimensions chrome.capture(filename); var selector_rect = chrome.getRect(selector); // so that there is no extra dependency if (selector_rect.width > 0 && selector_rect.height > 0) // from using other libraries or creating html canvas casper.thenOpen(file_url(filename), function() {casper . capture(filename, // spaces around . to avoid replacing {top: selector_rect.top, left: selector_rect.left, width: selector_rect.width, height: selector_rect.height}); -casper.thenOpen('about:blank');});}; // reset phantomjs browser state +casper.thenOpen('about:blank');});}; // reset phantomjs browser state */ + +chrome.captureSelector = function(filename,selector) { // capture screenshot of selector to png/jpg/jpeg format +var selector_rect = chrome.getRect(selector); if (selector_rect.width > 0 && selector_rect.height > 0) +{var format = 'png'; var quality = 80; var fromSurface = true; var screenshot_data = ''; // options not implemented +if ((filename.substr(-3).toLowerCase() == 'jpg') || (filename.substr(-4).toLowerCase() == 'jpeg')) format = 'jpeg'; +var clip = {x:selector_rect.left, y:selector_rect.top, width:selector_rect.width, height:selector_rect.height, scale:1}; +var ws_message = +chrome_step('Page.captureScreenshot',{format: format, quality: quality, clip: clip, fromSurface: fromSurface}); +try {var ws_json = JSON.parse(ws_message); screenshot_data = ws_json.result.data;} catch(e) {screenshot_data = '';} +var fs = require('fs'); fs.write(filename,chrome.decode(screenshot_data),'wb');}} chrome.upload = function(selector,filename) { // upload function to upload file to provided selector if ((selector.toString().length >= 16) && (selector.toString().substr(0,16) == 'xpath selector: ')) diff --git a/src/test/positive_test.signature b/src/test/positive_test.signature index 2b6ae0c8..6840a95e 100644 --- a/src/test/positive_test.signature +++ b/src/test/positive_test.signature @@ -603,13 +603,24 @@ else var ws_message = chrome_step('Page.captureScreenshot',{format: format, qual try {var ws_json = JSON.parse(ws_message); screenshot_data = ws_json.result.data;} catch(e) {screenshot_data = '';} var fs = require('fs'); fs.write(filename,chrome.decode(screenshot_data),'wb');}; +/* // backup of previous captureSelector implementation to use Page.captureScreenshot with clipping directly chrome.captureSelector = function(filename,selector) { // capture screenshot of selector to png/jpg/jpeg format // first capture entire screen, then use casperjs / phantomjs browser to crop image base on selector dimensions chrome.capture(filename); var selector_rect = chrome.getRect(selector); // so that there is no extra dependency if (selector_rect.width > 0 && selector_rect.height > 0) // from using other libraries or creating html canvas casper.thenOpen(file_url(filename), function() {casper . capture(filename, // spaces around . to avoid replacing {top: selector_rect.top, left: selector_rect.left, width: selector_rect.width, height: selector_rect.height}); -casper.thenOpen('about:blank');});}; // reset phantomjs browser state +casper.thenOpen('about:blank');});}; // reset phantomjs browser state */ + +chrome.captureSelector = function(filename,selector) { // capture screenshot of selector to png/jpg/jpeg format +var selector_rect = chrome.getRect(selector); if (selector_rect.width > 0 && selector_rect.height > 0) +{var format = 'png'; var quality = 80; var fromSurface = true; var screenshot_data = ''; // options not implemented +if ((filename.substr(-3).toLowerCase() == 'jpg') || (filename.substr(-4).toLowerCase() == 'jpeg')) format = 'jpeg'; +var clip = {x:selector_rect.left, y:selector_rect.top, width:selector_rect.width, height:selector_rect.height, scale:1}; +var ws_message = +chrome_step('Page.captureScreenshot',{format: format, quality: quality, clip: clip, fromSurface: fromSurface}); +try {var ws_json = JSON.parse(ws_message); screenshot_data = ws_json.result.data;} catch(e) {screenshot_data = '';} +var fs = require('fs'); fs.write(filename,chrome.decode(screenshot_data),'wb');}} chrome.upload = function(selector,filename) { // upload function to upload file to provided selector if ((selector.toString().length >= 16) && (selector.toString().substr(0,16) == 'xpath selector: '))