SlideShare a Scribd company logo
1 of 35
Hacking the Browser
With Puppeteer-Sharp
Darío Kondratiuk
.NET Senior Developer - MultiTracks.com
Author of Puppeteer-Sharp
@kblok - @hardkoded
www.hardkoded.com
Hacking the Browser
With Puppeteer-Sharp
Darío Kondratiuk
.NET Senior Developer @ MultiTracks.com
Author of Puppeteer-Sharp
@hardkoded - @kblok
www.hardkoded.com
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Headless Browsers
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Headless Browsers
● July 4, 2017 => Google Chrome 59
○ chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Headless Browsers
● July 4, 2017 => Google Chrome 59
○ chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/
● August 8, 2017 => Firefox 55
● August 16, 2017 => Puppeteer v0.9
● January 12, 2018 => Puppeteer v1.0
● March 1, 2018 => Puppeteer Sharp v0.1
● April 27, 2018 => Edge DevTools Protocol v0.1
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
WebDriver vs Headless Browsers
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
WebDriver
WebDriver is a remote control interface that enables
introspection and control of user agents. It provides a
platform- and language-neutral wire protocol as a way for out-
of-process programs to remotely instruct the behavior of web
browsers.
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Use Cases
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Screenshots
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
[HttpGet("{owner}/{repo}")]
public async Task<FileContentResult> Get(string owner, string repo)
{
var contributorsPage = $"https://github.com/{owner}/{repo}/graphs/contributors";
using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false
}))
using (var page = await browser.NewPageAsync())
{
await page.GoToAsync(contributorsPage);
await page.WaitForSelectorAsync(".contrib-person");
var element = await page.QuerySelectorAsync("#contributors");
var image = await element.ScreenshotDataAsync();
return File(image, "image/png");
}
}
PDFs
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
[HttpGet("{owner}/{post}")]
public async Task<FileContentResult> Get(string author, string post)
{
var contributorsPage = $"https://medium.com/{author}/{post}";
using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
}))
using (var page = await browser.NewPageAsync())
{
await page.GoToAsync(contributorsPage);
await page.WaitForSelectorAsync("HEADER");
await page.EvaluateExpressionAsync("document.querySelector('HEADER').remove();");
var pdf = await page.PdfDataAsync();
return File(pdf, "application/pdf");
}
}
Web Scraping
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
var url = "https://www.despegar.com.ar/shop/flights/results/roundtrip/BUE/MDZ/2018-12-01/2018-12-08/1";
using (var browser = await Puppeteer.LaunchAsync(options))
using (var page = await browser.NewPageAsync())
{
await page.GoToAsync(url, WaitUntilNavigation.Networkidle0);
await page.WaitForSelectorAsync("buy-button");
var bestPrice = await page.EvaluateFunctionAsync<string>(@"() => {
var elements = document.querySelectorAll('.main-content .price-amount');
return elements.length ? elements[0].innerText : '0';
}");
Console.WriteLine($"Best price for Mendoza {bestPrice}");
await Task.Delay(60000);
}
UI Testing
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
[Fact]
public async Task ShouldHonorThePrice()
{
//Previous Code
var clickElement = await page.EvaluateExpressionHandleAsync(@"
document.querySelectorAll('.main-content buy-button:first-child A')[0]")
as ElementHandle;
await clickElement.ClickAsync();
await page.WaitForSelectorAsync(".price-container .amount");
var checkoutPrice = await page.EvaluateExpressionAsync<string>(@"
document.querySelectorAll('.price-container .amount')[0].innerText
");
Assert.Equal(bestPrice, checkoutPrice);
}
Task Automation
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
DEMO
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
More examples
https://github.com/GoogleChromeLabs/puppeteer-examples
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Even more examples
https://github.com/checkly/puppeteer-examples
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Don’ts
● DDoS Attacks
● Unethical Web Scraping
● Fake page loads
● Credential Stuffing
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Puppeteer the world!
● Puppeteer Recorder
● Rendertron
● Checkly
● Contributors!
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Give Back
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
The power of a Star
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
Thank you!
https://developer.mozilla.org/en-US/docs/Web/WebDriver October 4th, 5th & 6th 2018.NET Conf AR v2018
@hardkoded - @kblok
www.hardkoded.com

More Related Content

What's hot

What's hot (20)

Writing native Linux desktop apps with JavaScript
Writing native Linux desktop apps with JavaScriptWriting native Linux desktop apps with JavaScript
Writing native Linux desktop apps with JavaScript
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
gRPC - RPC rebirth?
gRPC - RPC rebirth?gRPC - RPC rebirth?
gRPC - RPC rebirth?
 
Seo Audit Demo
Seo Audit DemoSeo Audit Demo
Seo Audit Demo
 
API for Beginners
API for BeginnersAPI for Beginners
API for Beginners
 
Flutter for web
Flutter for webFlutter for web
Flutter for web
 
Git & GitHub for Beginners
Git & GitHub for BeginnersGit & GitHub for Beginners
Git & GitHub for Beginners
 
CSS
CSSCSS
CSS
 
Golang Template
Golang TemplateGolang Template
Golang Template
 
Belajar Dasar-Dasar GIT
Belajar Dasar-Dasar GITBelajar Dasar-Dasar GIT
Belajar Dasar-Dasar GIT
 
REST vs gRPC: Battle of API's
REST vs gRPC: Battle of API'sREST vs gRPC: Battle of API's
REST vs gRPC: Battle of API's
 
Technical Tips: Visual Regression Testing and Environment Comparison with Bac...
Technical Tips: Visual Regression Testing and Environment Comparison with Bac...Technical Tips: Visual Regression Testing and Environment Comparison with Bac...
Technical Tips: Visual Regression Testing and Environment Comparison with Bac...
 
Introduction to headless browsers
Introduction to headless browsersIntroduction to headless browsers
Introduction to headless browsers
 
BrightonSEO 2023 - Introduction to Search Engines Beyond Google - N Witczyk.pdf
BrightonSEO 2023 - Introduction to Search Engines Beyond Google - N Witczyk.pdfBrightonSEO 2023 - Introduction to Search Engines Beyond Google - N Witczyk.pdf
BrightonSEO 2023 - Introduction to Search Engines Beyond Google - N Witczyk.pdf
 
Puppeteer can automate that! - AmsterdamJS
Puppeteer can automate that! - AmsterdamJSPuppeteer can automate that! - AmsterdamJS
Puppeteer can automate that! - AmsterdamJS
 
Pubcon 2023 - A deep dive into the latest Google updates, from Lily Ray
Pubcon 2023 - A deep dive into the latest Google updates, from Lily RayPubcon 2023 - A deep dive into the latest Google updates, from Lily Ray
Pubcon 2023 - A deep dive into the latest Google updates, from Lily Ray
 
Google Analytics Training - full 2017
Google Analytics Training - full 2017Google Analytics Training - full 2017
Google Analytics Training - full 2017
 
Introduction to PWA Studio by Vijay Golani
Introduction to PWA Studio by Vijay GolaniIntroduction to PWA Studio by Vijay Golani
Introduction to PWA Studio by Vijay Golani
 
International SEO: The Weird Technical Parts - Pubcon Vegas 2019 Patrick Stox
International SEO: The Weird Technical Parts - Pubcon Vegas 2019 Patrick StoxInternational SEO: The Weird Technical Parts - Pubcon Vegas 2019 Patrick Stox
International SEO: The Weird Technical Parts - Pubcon Vegas 2019 Patrick Stox
 
Hacking GA4 for SEO - Brighton SEO - Apr 2023
Hacking GA4 for SEO - Brighton SEO - Apr 2023Hacking GA4 for SEO - Brighton SEO - Apr 2023
Hacking GA4 for SEO - Brighton SEO - Apr 2023
 

Similar to Hacking the browser with puppeteer sharp .NET conf AR 2018

夜宴42期《Gadgets》
夜宴42期《Gadgets》夜宴42期《Gadgets》
夜宴42期《Gadgets》
Koubei Banquet
 
[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design
Christopher Schmitt
 
Testing of javacript
Testing of javacriptTesting of javacript
Testing of javacript
Lei Kang
 

Similar to Hacking the browser with puppeteer sharp .NET conf AR 2018 (20)

Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017
 
Front End Development for Back End Developers - vJUG24 2017
Front End Development for Back End Developers - vJUG24 2017Front End Development for Back End Developers - vJUG24 2017
Front End Development for Back End Developers - vJUG24 2017
 
夜宴42期《Gadgets》
夜宴42期《Gadgets》夜宴42期《Gadgets》
夜宴42期《Gadgets》
 
Banquet 42
Banquet 42Banquet 42
Banquet 42
 
[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design[convergese] Adaptive Images in Responsive Web Design
[convergese] Adaptive Images in Responsive Web Design
 
Google Chronicles: Analytics And Chrome
Google Chronicles: Analytics And ChromeGoogle Chronicles: Analytics And Chrome
Google Chronicles: Analytics And Chrome
 
Embedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceEmbedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to Maintenance
 
Keypoints html5
Keypoints html5Keypoints html5
Keypoints html5
 
Microservices for the Masses with Spring Boot, JHipster, and OAuth - Jforum S...
Microservices for the Masses with Spring Boot, JHipster, and OAuth - Jforum S...Microservices for the Masses with Spring Boot, JHipster, and OAuth - Jforum S...
Microservices for the Masses with Spring Boot, JHipster, and OAuth - Jforum S...
 
URL Design
URL DesignURL Design
URL Design
 
Building AR and VR Experiences for Web Apps with JavaScript
Building AR and VR Experiences for Web Apps with JavaScriptBuilding AR and VR Experiences for Web Apps with JavaScript
Building AR and VR Experiences for Web Apps with JavaScript
 
Testing of javacript
Testing of javacriptTesting of javacript
Testing of javacript
 
Atlassian User Group NYC April 27 2017 ScriptRunner Workshop
Atlassian User Group NYC April 27 2017 ScriptRunner WorkshopAtlassian User Group NYC April 27 2017 ScriptRunner Workshop
Atlassian User Group NYC April 27 2017 ScriptRunner Workshop
 
Introduction to python scrapping
Introduction to python scrappingIntroduction to python scrapping
Introduction to python scrapping
 
Developing web applications in 2010
Developing web applications in 2010Developing web applications in 2010
Developing web applications in 2010
 
Choose Your Own Adventure with JHipster & Kubernetes - Utah JUG 2020
Choose Your Own Adventure with JHipster & Kubernetes - Utah JUG 2020Choose Your Own Adventure with JHipster & Kubernetes - Utah JUG 2020
Choose Your Own Adventure with JHipster & Kubernetes - Utah JUG 2020
 
ChromeとAndroidの過去・現在・未来
ChromeとAndroidの過去・現在・未来ChromeとAndroidの過去・現在・未来
ChromeとAndroidの過去・現在・未来
 
GlobalLogic Test Automation Online TechTalk “Playwright — A New Hope”
GlobalLogic Test Automation Online TechTalk “Playwright — A New Hope”GlobalLogic Test Automation Online TechTalk “Playwright — A New Hope”
GlobalLogic Test Automation Online TechTalk “Playwright — A New Hope”
 
Timings API: Performance Assertion during the functional testing
 Timings API: Performance Assertion during the functional testing Timings API: Performance Assertion during the functional testing
Timings API: Performance Assertion during the functional testing
 
It is not HTML5. but ... / HTML5ではないサイトからHTML5を考える
It is not HTML5. but ... / HTML5ではないサイトからHTML5を考えるIt is not HTML5. but ... / HTML5ではないサイトからHTML5を考える
It is not HTML5. but ... / HTML5ではないサイトからHTML5を考える
 

More from Darío Kondratiuk (6)

Novedades en C# 10, .NET 6 y ASP.NET 6
Novedades en C# 10, .NET 6 y ASP.NET 6Novedades en C# 10, .NET 6 y ASP.NET 6
Novedades en C# 10, .NET 6 y ASP.NET 6
 
FreeCodeCampBA: Hoy te convertís en un héroe
FreeCodeCampBA: Hoy te convertís en un héroeFreeCodeCampBA: Hoy te convertís en un héroe
FreeCodeCampBA: Hoy te convertís en un héroe
 
Web automation para developers
Web automation para developersWeb automation para developers
Web automation para developers
 
Async programming: From 0 to task.IsComplete - es
Async programming: From 0 to task.IsComplete - esAsync programming: From 0 to task.IsComplete - es
Async programming: From 0 to task.IsComplete - es
 
vOpen19 Uruguay - Hoy te convertis en un heroe
vOpen19 Uruguay - Hoy te convertis en un heroevOpen19 Uruguay - Hoy te convertis en un heroe
vOpen19 Uruguay - Hoy te convertis en un heroe
 
Hoy te convertis en un héroe - AOM 2019
Hoy te convertis en un héroe - AOM 2019Hoy te convertis en un héroe - AOM 2019
Hoy te convertis en un héroe - AOM 2019
 

Recently uploaded

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 

Recently uploaded (20)

AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...
WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...
WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...
 
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAMWSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 

Hacking the browser with puppeteer sharp .NET conf AR 2018

Editor's Notes

  1. Contributors images
  2. Contributors images
  3. Contributors images
  4. Contributors images
  5. Contributors images
  6. Contributors images
  7. Contributors images
  8. Contributors images
  9. Contributors images
  10. Contributors images
  11. Contributors images
  12. Contributors images
  13. Contributors images
  14. Contributors images
  15. Contributors images
  16. Chrome tells you when it runs in automation mode
  17. Contributors images
  18. Contributors images
  19. Contributors images
  20. Contributors images