How to take a screenshot by passing coordinates and dimensions in Playwright? - playwright

Is it possible to take a screenshot by passing coordinates and dimensions (like the output of getBoundingClientRect()) via Playwright?
Looking at their screenshots API, it seems I need to select a locator first, but the locator API doesn't seem to accept coordinates as arguments.
await page.locator('.header').screenshot({ path: 'screenshot.png' });

I believe the ability to screenshot specific co-ordinates are only available at page level by passing in the PageScreenshotOptions as an option:
await page.screenshot({ clip: {height: 100, width: 100, x: 0, y: 0 } });

Related

Image URI not loading in flutter ios

I'm creating a native app where I'm using image URI instead of png or jpg image just to reduce the size. But the issue is that the image URI is not loading/showing in ios. I tried on android and the web it's working.
Here is the code
//Image URI
var _hello_Image_Uri = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnN2Z2pzPSJodHRwOi8vc3ZnanMuY29tL3N2Z2pzIiB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgeD0iMCIgeT0iMCIgdmlld0JveD0iMCAwIDQ5NS45NCA0OTUuOTQiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiIGNsYXNzPSIiPjxnPjxwYXRoIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZD0ibTQxNC43MzcgNTkuOThjLTkuNTA2IDM1LjQ4NS0zNy43MzEgMTQwLjgyOS00Ny45MSAxNzguODIgNy45MTYgNy45MTYgMTcuNTA1IDE2Ljk3IDI1LjE0IDM0LjU2IDEwLjA3NCAyMy4wNzYgOCAzNS42ODkgOCA5MC41OCAwIDcyLjktNTkuMSAxMzItMTMyIDEzMmgtNTZjLTczLjA5IDAtMTMyLTU5LjI5OS0xMzItMTMyIDAtNjcuNDM5IDAgMTIyLjEwNSAwLTE2NCAwLTE3LjY3OSAxNC4zMTktMzIgMzItMzIgMTcuNjcgMCAzMiAxNC4zMyAzMiAzMnYtMjhjMC0yMy44OTQgMjIuODY4LTQxLjIzNCA0Ni4wNS0zNC41Ny0yMi4yNTktODMuMDU5LTE2Ljg0My02Mi44NDgtMjQuNjgtOTIuMS0yLjU3LTkuNi0xLjAxLTE5LjM0IDMuNTktMjcuMzIgMTUuOTU5LTI3LjU2NiA1Ny42NDUtMjIuMzE4IDY1Ljk2IDguNjggNC45NyAxOC41NTguMDQ5LjE5MiA0OC41OCAxODEuMzFoMTcuMDhjMi4wMzMtNy41ODUgNDEuOTktMTU2LjcwMyA0NC42NC0xNjYuNTkgNS4xNS0xOS4yMSAyNC44OS0zMC42IDQ0LjA5LTI1LjQ2IDE5LjE4NyA1LjEzNyAzMC42MTEgMjQuODUxIDI1LjQ2IDQ0LjA5eiIgZmlsbD0iI2Y5Y2ZhYyIgZGF0YS1vcmlnaW5hbD0iI2Y5Y2ZhYyIgc3R5bGU9IiI+PC9wYXRoPjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0iI2ZmZTRjYyI+PHBhdGggZD0ibTIzMS45NjcgMTkxLjk0di0yMGMwLTE5LjQ2LTEwLjc0LTM2LjQ1LTI2LjYtNDUuMzZsLTMxLjktMTE0LjgzYzE4Ljc1NS0yMC43MjMgNTMuOTUxLTEyLjk2OCA2MS40MiAxNC44OCA2LjA1MSAyMi41OTYtMS42NjUtNi4yMDUgNDQuMjkgMTY1LjMxeiIgZmlsbD0iI2ZmZTRjYyIgZGF0YS1vcmlnaW5hbD0iI2ZmZTRjYyIgc3R5bGU9IiI+PC9wYXRoPjxwYXRoIGQ9Im00MTQuNzM3IDU5Ljk4Yy05LjY0OCAzNi4wMTItMzQuMjE4IDEyNy43MTYtNDMuMTMgMTYwLjk4LTEwLjA1My0xMC4wNjYtMjYuNDk4LTI5LjAyLTU4Ljg0LTI5LjAyaC03LjkzYzcuMjUxLTI3LjA2MSAzNS42NjUtMTMzLjEwNiA0MC4zNS0xNTAuNTkgNS4xNS0xOS4yMSAyNC44OS0zMC42IDQ0LjA5LTI1LjQ2IDE5LjE4NyA1LjEzNyAzMC42MTEgMjQuODUxIDI1LjQ2IDQ0LjA5eiIgZmlsbD0iI2ZmZTRjYyIgZGF0YS1vcmlnaW5hbD0iI2ZmZTRjYyIgc3R5bGU9IiI+PC9wYXRoPjxwYXRoIGQ9Im0xOTkuOTY3IDIyMy45NGMwIDE2LjU4IDUuNjQgMzEuODcgMTUuMSA0NC4wNi0zLjA4NiAxMy40NDUtMTMuNjQgMjMuOTktMjcuMSAyNy4wNS0xNi4wMy0zLjY0LTI4LTE3Ljk4LTI4LTM1LjExdi0xMTcuOTRjMjMuNTk5LTE1LjgwMiA1NiAuOTY3IDU2IDI5Ljk0djI0LjI5Yy05LjYwNiA1LjUyMy0xNiAxNS44NzctMTYgMjcuNzF6IiBmaWxsPSIjZmZlNGNjIiBkYXRhLW9yaWdpbmFsPSIjZmZlNGNjIiBzdHlsZT0iIj48L3BhdGg+PHBhdGggZD0ibTE0My45NjcgMTk5Ljk0djcyYzAgMTQuODk2LTEwLjE4NSAyNy40NS0yNCAzMC45OS0xMy44LTMuNTUtMjQtMTYuMDgtMjQtMzAuOTl2LTk5LjcyYzIxLjE1OS0xMi4yMTggNDggMi45OTQgNDggMjcuNzJ6IiBmaWxsPSIjZmZlNGNjIiBkYXRhLW9yaWdpbmFsPSIjZmZlNGNjIiBzdHlsZT0iIj48L3BhdGg+PHBhdGggZD0ibTM5OS45NjcgMzYzLjk0YzAgNDAuNjYtMTguMzggNzcuMDItNDcuMjkgMTAxLjI0LTE4LjE3IDkuNDMtMzguODIgMTQuNzYtNjAuNzEgMTQuNzZoLTU2Yy03Mi41NjIgMC0xMzItNTguNzgtMTMyLTEzMnYtMjguNjdjMTYuOTYgMi44NyAzNC4zMDItMy41MzkgNDUuMzYtMTcuMjIuMDc4LS4xMTYuMDU3LS4wNzIuMTItLjA0IDI2LjY5NSAxOS40NjkgNjQuODI0IDkuMjYzIDc4LjIxLTIxLjM2IDIyLjAzIDE3LjI4MyA0Mi4wNzQgMTUuMjkgNjIuMjggMTUuMjktNTAuMjM4IDE4LjA3LTg2LjIwMyA2NC41MDctODkuNjkgMTE5LjMtLjI3NSA0LjY2NCAzLjM3NCA4LjMzOSA3Ljc2IDguNDcgNC4zMi4xMyA3LjkzLTMuMjEgOC4yMS03LjUzIDMuNjY3LTU3LjE4MSA0Ny40MDktMTAzLjY2OSAxMDMuNzUtMTExLjE4IDAtOS4wNzEtMi45MS0xNy41NjEtNy43OC0yNC40MS0uNTktLjkyOCAzLjY1Ny0uNjUtNDAuMjItLjY1LTMxLjA2MiAwLTU2LTI1LjIwNy01Ni01NiAwLTguODUzIDcuMTYtMTYgMTYtMTZoODAuOGMxNC44NiAwIDI5LjEgNS45IDM5LjYgMTYuNCAxOS4zMjEgMTkuMzIxIDMwLjgwMiAyOC43NTIgMzkuNiA0OS4wMiAxMC4wNzQgMjMuMDc2IDggMzUuNjg5IDggOTAuNTh6IiBmaWxsPSIjZmZlNGNjIiBkYXRhLW9yaWdpbmFsPSIjZmZlNGNjIiBzdHlsZT0iIj48L3BhdGg+PC9nPjwvZz48L3N2Zz4=";
Container(
width: 120,
height: 120,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: Colors.lightGreen,
),
child: Image.network(_hello_Image_Uri),
)
where
Image.network(_hello_Image_Uri),
Issue
════════ Exception caught by image resource service ════════════════════════════
The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI file:///PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnN2Z2pzPSJodHRwOi8vc3ZnanMuY29tL3N2Z2pzIiB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgeD0iMCIgeT0iMCIgdmlld0JveD0iMCAwIDQ5NS45NCA0OTUuOTQiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiIGNsYXNzPSIiPjxnPjxwYXRoIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZD0ibTQxNC43MzcgNTkuOThjLTkuNTA2IDM1LjQ4NS0zNy43MzEgMTQwLjgyOS00Ny45MSAxNzguODIgNy45MTYgNy45MTYgMTcuNTA1IDE2Ljk3IDI1LjE0IDM0LjU2IDEwLjA3NCAyMy4wNzYgOCAzNS42ODkgOCA5MC41OCAwIDcyLjktNTkuMSAxMzItMTMyIDEzMmgtNTZjLTczLjA5IDAtMTMyLTU5LjI5OS0xMzItMTMyIDAtNjcuNDM5IDAgMTIyLjEwNSAwLTE2NCAwLTE3LjY3OSAxNC4zMTktMzIgMzItMzIgMTcuNjcgMCAzMiAxNC4zMyAzMiAzMnYtMjhjMC0yMy44OTQgMjIuODY4LTQxLjIzNCA0Ni4wNS0zNC41Ny0yMi4yNTktODMuMDU5LTE2Ljg0My02Mi44NDgtMjQuNjgtOTIuMS0yLjU3LTkuNi0xLjAxLTE5LjM0IDMuNTktMjcuMzIgMTUuOTU5LTI3LjU2NiA1Ny42NDUtMjIuMzE4IDY1Ljk2IDguNjggNC45NyAxOC41NTguMDQ5LjE5MiA0OC41OCAxODEuMzFoMTcuMDhjMi4wMzMtNy41ODUgNDEuOTktMTU2LjcwMyA0NC42NC0xNjYuNTkgNS4xNS0xOS4yMSAyNC44OS0zMC42IDQ0LjA5LTI1LjQ2IDE5LjE4NyA1LjEzNyAzMC42MTEgMjQuODUxIDI1LjQ2IDQ0LjA5eiIgZmlsbD0iI2Y5Y2ZhYyIgZGF0YS1vcmlnaW5hbD0iI2Y5Y2ZhYyIgc3R5bGU9IiI+PC9wYXRoPjxnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0iI2ZmZTRjYyI+PHBhdGggZD0ibTIzMS45NjcgMTkxLjk0di0yMGMwLTE5LjQ2LTEwLjc0LTM2LjQ1LTI2LjYtNDUuMzZsLTMxLjktMTE0LjgzYzE4Ljc1NS0yMC43MjMgNTMuOTUxLTEyLjk2OCA2MS40MiAxNC44OCA2LjA1MSAyMi41OTYtMS42NjUtNi4yMDUgNDQuMjkgMTY1LjMxeiIgZmlsbD0iI2ZmZTRjYyIgZGF0YS1vcmlnaW5hbD0iI2ZmZTRjYyIgc3R5bGU9IiI+PC9wYXRoPjxwYXRoIGQ9Im00MTQuNzM3IDU5Ljk4Yy05LjY0OCAzNi4wMTItMzQuMjE4IDEyNy43MTYtNDMuMTMgMTYwLjk4LTEwLjA1My0xMC4wNjYtMjYuNDk4LTI5LjAyLTU4Ljg0LTI5LjAyaC03LjkzYzcuMjUxLTI3LjA2MSAzNS42NjUtMTMzLjEwNiA0MC4zNS0xNTAuNTkgNS4xNS0xOS4yMSAyNC44OS0zMC42IDQ0LjA5LTI1LjQ2IDE5LjE4NyA1LjEzNyAzMC42MTEgMjQuODUxIDI1LjQ2IDQ0LjA5eiIgZmlsbD0iI2ZmZTRjYyIgZGF0YS1vcmlnaW5hbD0iI2ZmZTRjYyIgc3R5bGU9IiI+PC9wYXRoPjxwYXRoIGQ9Im0xOTkuOTY3IDIyMy45NGMwIDE2LjU4IDUuNjQgMzEuODcgMTUuMSA0NC4wNi0zLjA4NiAxMy40NDUtMTMuNjQgMjMuOTktMjcuMSAyNy4wNS0xNi4wMy0zLjY0LTI4LTE3Ljk4LTI4LTM1LjExdi0xMTcuOTRjMjMuNTk5LTE1LjgwMiA1NiAuOTY3IDU2IDI5Ljk0djI0LjI5Yy05LjYwNiA1LjUyMy0xNiAxNS44NzctMTYgMjcuNzF6IiBmaWxsPSIjZmZlNGNjIiBkYXRhLW9yaWdpbmFsPSIjZmZlNGNjIiBzdHlsZT0iIj48L3BhdGg+PHBhdGggZD0ibTE0My45NjcgMTk5Ljk0djcyYzAgMTQuODk2LTEwLjE4NSAyNy40NS0yNCAzMC45OS0xMy44LTMuNTUtMjQtMTYuMDgtMjQtMzAuOTl2LTk5LjcyYzIxLjE1OS0xMi4yMTggNDggMi45OTQgNDggMjcuNzJ6IiBmaWxsPSIjZmZlNGNjIiBkYXRhLW9yaWdpbmFsPSIjZmZlNGNjIiBzdHlsZT0iIj48L3BhdGg+PHBhdGggZD0ibTM5OS45NjcgMzYzLjk0YzAgNDAuNjYtMTguMzggNzcuMDItNDcuMjkgMTAxLjI0LTE4LjE3IDkuNDMtMzguODIgMTQuNzYtNjAuNzEgMTQuNzZoLTU2Yy03Mi41NjIgMC0xMzItNTguNzgtMTMyLTEzMnYtMjguNjdjMTYuOTYgMi44NyAzNC4zMDItMy41MzkgNDUuMzYtMTcuMjIuMDc4LS4xMTYuMDU3LS4wNzIuMTItLjA0IDI2LjY5NSAxOS40NjkgNjQuODI0IDkuMjYzIDc4LjIxLTIxLjM2IDIyLjAzIDE3LjI4MyA0Mi4wNzQgMTUuMjkgNjIuMjggMTUuMjktNTAuMjM4IDE4LjA3LTg2LjIwMyA2NC41MDctODkuNjkgMTE5LjMtLjI3NSA0LjY2NCAzLjM3NCA4LjMzOSA3Ljc2IDguNDcgNC4zMi4xMyA3LjkzLTMuMjEgOC4yMS03LjUzIDMuNjY3LTU3LjE4MSA0Ny40MDktMTAzLjY2OSAxMDMuNzUtMTExLjE4IDAtOS4wNzEtMi45MS0xNy41NjEtNy43OC0yNC40MS0uNTktLjkyOCAzLjY1Ny0uNjUtNDAuMjItLjY1LTMxLjA2MiAwLTU2LTI1LjIwNy01Ni01NiAwLTguODUzIDcuMTYtMTYgMTYtMTZoODAuOGMxNC44NiAwIDI5LjEgNS45IDM5LjYgMTYuNCAxOS4zMjEgMTkuMzIxIDMwLjgwMiAyOC43NTIgMzkuNiA0OS4wMiAxMC4wNzQgMjMuMDc2IDggMzUuNjg5IDggOTAuNTh6IiBmaWxsPSIjZmZlNGNjIiBkYXRhLW9yaWdpbmFsPSIjZmZlNGNjIiBzdHlsZT0iIj48L3BhdGg+PC9nPjwvZz48L3N2Zz4=
Image.network is for images obtained through a network as the name implies. If you look at the implementation of Image.network, you'll find that it will attempt to make a GET request with an HTTP client. Since there is no host in the URI string you show, this request fails as expected. Source.
There's a lot going wrong with what you're trying to do here. Reducing image size by using SVG is a good idea since I guess you had a vector source, but understand that Flutter does not native support for SVG. It may work on the web when using canvaskit, but not for other platforms. You will need to use the flutter_svg package and can follow this SO answer to find a way to make it work on web as well. I would use the SvgPicture.string or SvgPicture.asset constructors instead of what they show in their answer so that there are no unecessary network requests. This may be more trouble than it's worth and support will be more flakey than using a raster image, but that's up to you. Also be aware that using this package and the canvaskit renderer will increase overall application size, which may not be worth it for only a few images.
Code from linked answer:
class CrossPlatformSvg {
static Widget asset(
String assetPath, {
double width,
double height,
BoxFit fit = BoxFit.contain,
Color color,
alignment = Alignment.center,
String semanticsLabel,
}) {
// `kIsWeb` is a special Flutter variable that just exists
// Returns true if we're on web, false for mobile
if (kIsWeb) {
return Image.network(
assetPath,
width: width,
height: height,
fit: fit,
color: color,
alignment: alignment,
);
} else {
return SvgPicture.network(
assetPath,
width: width,
height: height,
fit: fit,
color: color,
alignment: alignment,
placeholderBuilder: (_) => Container(
width: 30,
height: 30,
padding: EdgeInsets.all(30),
child: CircularIndicator(),
),
);
}
}
}
Your current attempt also unnecessarily increases the amount of data that needs to be stored because you're using a base64 encoded string. Base64 encoding will increase the amount of data that needs to be stored by ~1.5 times, which goes against your intention of reducing size.

Can experimental features like offscreenanvas be enabled in electron?

A 2d or webgl canvas rendered using OffscreenCanvas could have some interesting performance benefits. I'm wondering if there is a way to enable it in the latest electron.
Setting the experimentalFeatures flag as discussed in this thread did not work.
The following console logs:
console.log('canvasNode', canvasNode)
console.log('transferControlToOffscreen', canvasNode.transferControlToOffscreen)
console.log('OffscreenCanvas', window.OffscreenCanvas)
Output this results:
And the way I am instantiating the browser window which logs this is:
win = new BrowserWindow({
width: 1200,
height: 700,
webPreferences: { experimentalFeatures: true }
})
Two links and a google later I found the answer on this github doc page
Since the offscreencanvas is a canvas related feature it is under a different flag called experimentalCanvasFeatures
In order to enable it I had to instantiate my browser window like so:
win = new BrowserWindow({
width: 1200,
height: 700,
webPreferences: { experimentalCanvasFeatures: true }
})
With experimentalCanvasFeatures instead of experimentalFeatures.
This resulted in the following console output:

Getting Ink Strokes in MyScript

I'm working with MyScript, and I noticed that for the web API (find examples here: http://doc.myscript.com/MyScriptCloud/3.1.0/myscript-cloud/examples.html), a "stroke" type is required, as well as all of the coordinates describing the stroke.
I'm wondering what software I should use to generate these strokes, or how I could program it myself? There's nothing in the official documentation.
Thanks for your time.
The stroke type expected by the server is a json object with x, y attributes, containing both arrays of integer. These values represent x,y coordinates user input while writing on the device touchscreen. You can collect and add timestamp as an optional ‘t’ attribut of the JSON stroke type structure.
As a first option, you can use our webcomponents : myscript-math-web, myscript-text-web or even MyScriptJS to manage the user ink capture and the rendering in a canvas.
You can also grab the user handwriting by yourself, in this case we recommend you to use (jquery PEP)[https://github.com/jquery/PEP] (Pointer Event Polyfill) that will help you to manage user touchscreen events, namely pointer events.
You will have to listen for pointerdown, pointermove and pointerup events. Once such event occurs, add the event coordinates to your structure this way, for instance:
var myStroke;
document.querySelector('#myCanvasId').addEventListener('pointerdown', function (e) {
e.preventDefault();
mystroke = {x : [], y : [], t : []};
mystroke.x.push(e.clientX);
mystroke.y.push(e.clientY);
mystroke.t.push(e.timestamp)
}, false);
document.querySelector('#myCanvasId').addEventListener('pointermove', function (e) {
e.preventDefault();
mystroke.x.push(e.clientX);
mystroke.y.push(e.clientY);
mystroke.t.push(e.timestamp)
}, false);
document.querySelector('#myCanvasId').addEventListener('pointerup', function (e) {
e.preventDefault();
mystroke.x.push(e.clientX);
mystroke.y.push(e.clientY);
mystroke.t.push(e.timestamp)
// Send your stroke to the server
mystroke = {};
}, false);
If you need more detailed explanation, you can have a look at this video. Details about digital ink capture at 10:40.

Click overlay marker in Google Maps with capybara-webkit

Is there a way to click a Google Maps overlay with capybara-webkit? What about Capybara using Selenium? I want to test the content of the info window once the marker is selected. I also want to test that there are n markers on the page.
To test that there are n markers on the page:
expect(find('.gmap_container')['data-markers'].split('},{').count).to eq(n)
This can be done, but requires a change to how you create your markers. You must instruct them to render as images rather than canvas elements:
new google.maps.Marker({
position: latLng,
animation: google.maps.Animation.DROP,
name: business.get('name'),
id: business.get('id'),
optimized: false, // <-- this is the stuff
title: business.get('name')
});
Then in your test, you can find('div[title="Business\ Title"]').click
If possible, you might want to consider doing this just for a test environment, but that's up to you and your needs.
Credit: http://blog.mojotech.com/selecting-google-maps-v3-markers-with-selenium-or-jquery/
Hope this helps!

using easing with effect() in jqueryUI

I'm trying to apply easing to a specific jqueryUI effect() and can't get it to work. According to this page, it should, but there are no code details:
http://api.jqueryui.com/1.8/effect/
I've tried:
$("#id").effect( "pulsate", {easing: "swing"} );
$("#id").effect( "pulsate", {"swing"} );
$("#id").effect({effect: "pulsate", easing: "swing"});
$("#id").effect( "pulsate", "swing" );
$("#id").effect( effect: "pulsate", easing: "swing" );
None work.
Recently, jQuery UI came out with a new website. In general, I've found it to be unhelpful at best and inaccurate at worst. I'm not sure that I'd trust the new site in this case since the jQuery effect docs for pulsate does not describe the same options.
If you want to just swing this particular element, you could use this code:
$("#id")
.animate({height: "hide", width: "hide"}, 1500, "swing")
.animate({height: "show", width: "show"}, 1500, "swing");
Here is an example of my suggested code in action.
If you'd like to do something else, say more and we'll try to help.
$('#id').effect( "highlight",{color:'#FFFF00',easing:'easeInExpo'},4000 );
I am using effect for highlighting an element after a scroll to event. easing is working for me in the above code.
I am running jQuery 1.8.

Resources