Best JavaScript code snippet using playwright-internal
english_words.js
Source: english_words.js
1'use strict';2define(['text!/example_data/english-words-by-freq.txt', 'underscore'],3 function(word_list_file, _){4 function ScoreEnglishWords(){5 this.log_messages = [];6 this.common_words_list = null;7 this.weights = {8 common_words: 100.0,9 non_printable: -2.0,10 longest_printable: 2.0,11 printable: 2.0,12 };13 }14 ScoreEnglishWords.long_word_list = null;15 /**16 * Cache this instance's word list.17 */18 ScoreEnglishWords.cacheLongWordList = function(common_words_list){19 ScoreEnglishWords.long_word_list = {20 list: common_words_list,21 regex: new RegExp('\\b(' + common_words_list.join('|') + ')\\b', 'ig')22 };23 };24 /**25 * Load up a list of frequently used english language words from a text file.26 * Called when module is loaded.27 */28 ScoreEnglishWords.commonWordsInit = function(word_list_file){29 var comment_re = /^#+.*/;30 var word_list_limit = 1000;31 ScoreEnglishWords.long_word_list = {};32 console.log('ScoreEnglishWords parsing score words list.');33 var word_list = word_list_file.split("\n");34 console.log('ScoreEnglishWords got list ' + word_list.length + ' lines.');35 /* Reject comment lines starting w # */36 word_list = _.reject(word_list, function(line){37 var is_comment = (comment_re.exec(line) != null);38 var is_too_short = line.length < 2;39 return is_comment || is_too_short;40 });41 /* Limit count */42 word_list = word_list.slice(0, word_list_limit);43 console.log('ScoreEnglishWords imported ' + word_list.length + ' words.');44 ScoreEnglishWords.cacheLongWordList(word_list);45 };46 /**47 * Count how many times a regex matches content.48 */49 ScoreEnglishWords.prototype.matchCount = function(re, content){50 var match = null, match_count = 0;51 if(!re.global) throw "Can't matchCount() with a Regexp that doesn't use the g flag.";52 while(re.exec(content) != null){53 match_count += 1;54 }55 return match_count;56 };57 ScoreEnglishWords.prototype.getCommonWordsRE = function(){58 if(ScoreEnglishWords.long_word_list.regex instanceof RegExp)59 return ScoreEnglishWords.long_word_list.regex;60 throw "ScoreEnglishWords.long_word_list not initialized yet.";61 };62 /**63 * Perform a series of tests and return a score higher the more64 * likely the content is english text.65 */66 ScoreEnglishWords.prototype.getScore = function(content){67 var scores = {};68 /* How many times common words appear. */69 var common_words_re = this.getCommonWordsRE();70 scores['common_words'] = (this.matchCount(common_words_re, content) * this.weights.common_words);71 /* Consecutive printable characters. */72 var printable_re = /([\x20-\x7E]{10}[\x20-\x7E]+)/g;73 var match = null;74 var printable_points = 0;75 var longest_printable = 0;76 var longest_printable_string = '';77 while(match = printable_re.exec(content)){78 var item = match[0];79 if(longest_printable < item.length){80 longest_printable_string = item;81 longest_printable = item.length;82 }83 printable_points += (item.length * this.weights.printable);84 }85 scores['longest_printable'] = longest_printable * this.weights.longest_printable;86 /* How many non-printable characters appear (negative score). */87 var nonprintable_re = /[^\x20-\x7E]+/g;88 var nonprintable_points = (this.matchCount(nonprintable_re, content) * this.weights.non_printable);89 var points = printable_points + scores['longest_printable'] + scores.common_words + nonprintable_points;90 this.progressLog("SCORE: Words: " + scores.common_words +91 " Printable: " + printable_points +92 " Nonprintable: " + nonprintable_points +93 " Longest Printable: " + scores['longest_printable'] + ' "' + longest_printable_string + '"' +94 " Total: " + points);95 return points;96 };97 // TODO repeated from challenge.98 /**99 * Log scoring messages.100 */101 ScoreEnglishWords.prototype.progressLog = function(message){102 //console.log("progress: " + message);103 this.log_messages.push(message);104 };105 ScoreEnglishWords.prototype.flushLog = function(show = true){106 var messages = this.log_messages;107 if(show && (messages.length > 0))108 console.log(messages.join("\n"));109 this.log_messages = [];110 return messages;111 };112 ScoreEnglishWords.commonWordsInit(word_list_file);113 return ScoreEnglishWords;...
processData.js
Source: processData.js
1import { map, filter, uniq } from 'lodash';2import spacetime from 'spacetime';3import { removeSpaces, removeNonprintableChars } from './utils';4const processData = (data) => {5 // system messages:6 const logMsgs = [7 "Messages you send to this group are now secured with end-to-end encryption",8 "You're now an admin",9 "changed the subject to"10 ];11 const quitMsgs = [12 "left",13 "removed"14 ];15 const joinMsgs = [16 "created this group",17 "added you",18 "joined using this group's invite link",19 ];20 const inviteMsgs = [21 "added",22 ];23 const attachMsgs = [24 "attached>",25 "omitted>",26 ];27 const systemMsgs = joinMsgs.concat(inviteMsgs, quitMsgs, logMsgs);28 const processTextData = (data) => {29 let participants = new Array;30 let msgs = new Array;31 const lines = data.split('\r');32 try {33 msgs = map(lines, (line) => {34 const datestring = removeNonprintableChars( line.split(',')[0].replace('\n', '') );35 const timestring = removeNonprintableChars( line.split(',')[1].split(':').slice(0,3).join(':').replace(' ','') );36 const datestringFormatted = datestring.split('/').map( (str) => { return parseInt(str); }).reverse();37 const datetime = spacetime(38 datestringFormatted39 .concat(40 timestring.split(':')41 )42 );43 const timestamp = Math.floor(datetime.epoch/1000);44 const datetimestring = datetime.format('dmy') + ' ' + datetime.format('time-h24');45 let content;46 let tl = line.split(',')[1].split(':');47 let precontent = removeNonprintableChars( tl.slice(3,tl.length).join(':') );48 let isSystem = precontent.indexOf(':') === -1;49 let participant;50 if (isSystem) {51 let newParticipant;52 let joins = filter(joinMsgs, (sm) => {53 if (precontent.toLowerCase().search(sm.toLowerCase()) !== -1) {54 newParticipant = removeSpaces( precontent.replace(sm,'') );55 participants.push(newParticipant);56 //console.log(newParticipant);57 return true;58 }59 });60 if (joins.length === 0) {61 let invites = filter(inviteMsgs, (sm) => {62 if (precontent.toLowerCase().search(sm.toLowerCase()) !== -1) {63 newParticipant = removeSpaces( precontent.replace(sm,'') );64 // TODO remove inviter65 //console.log(newParticipant);66 return true;67 }68 });69 }70 // check for unknown messages71 let knownMsgs = filter(systemMsgs, (sm) => {72 if (precontent.toLowerCase().search(sm.toLowerCase()) !== -1) {73 return true;74 }75 });76 if (knownMsgs.length === 0) {77 throw {78 name: 'Unknown Whatsapp system message',79 message: precontent80 }81 }82 // TODO split participant name and message83 content = removeSpaces(precontent.replace(newParticipant, ''));84 participant = newParticipant;85 } else {86 let precontent = tl.slice(3,tl.length).join(' ');87 participant = tl[3].replace(/^\s+|\s+$/g,'');88 // TODO split participant name and message89 content = removeSpaces(precontent.replace(participant, ''));90 if (typeof(participant) === 'string') {91 participants.push(participant);92 }93 }94 participant = participant || null;95 return {96 datestring,97 datetimestring,98 timestring,99 datetime,100 timestamp,101 isSystem,102 participant,103 content104 }105 });106 participants = uniq(participants);107 } catch (e) {108 console.log(e);109 }110 return {111 msgs,112 participants113 }114 }115 return processTextData(data);116}...
secrets.js
Source: secrets.js
1'use strict';2angular.module("openshiftConsole")3 .factory("SecretsService", function(){4 var groupSecretsByType = function(secrets) {5 var secretsByType = {6 source: [],7 image: [],8 other: []9 };10 _.each(secrets.by('metadata.name'), function(secret) {11 switch (secret.type) {12 case 'kubernetes.io/basic-auth':13 case 'kubernetes.io/ssh-auth':14 case 'Opaque':15 secretsByType.source.push(secret);16 break;17 case 'kubernetes.io/dockercfg':18 case 'kubernetes.io/dockerconfigjson':19 secretsByType.image.push(secret);20 break;21 default:22 secretsByType.other.push(secret);23 }24 });25 return secretsByType;26 };27 var decodeDockercfg = function(encodedData) {28 var decodedSecretData = {};29 var decodedData = JSON.parse(window.atob(encodedData));30 _.each(decodedData, function(data, serverName) {31 decodedSecretData[serverName] = {32 username: data.username,33 password: data.password,34 email: data.email35 };36 });37 return decodedSecretData;38 };39 var decodeDockerconfigjson = function(encodedData) {40 var decodedSecretData = {};41 var decodedData = JSON.parse(window.atob(encodedData));42 _.each(decodedData.auths, function(data, serverName) {43 var usernamePassword = window.atob(data.auth).split(":");44 decodedSecretData[serverName] = {45 username: usernamePassword[0],46 password: usernamePassword[1],47 email: data.email48 };49 });50 return decodedSecretData;51 };52 var decodeSecretData = function(secretData) {53 var nonPrintable = {};54 var decodedSecret = _.mapValues(secretData, function(data, paramName) {55 var decoded, isNonPrintable;56 switch (paramName) {57 case ".dockercfg":58 return decodeDockercfg(data);59 case ".dockerconfigjson":60 return decodeDockerconfigjson(data);61 default:62 decoded = window.atob(data);63 // Allow whitespace like newlines and tabs, but detect other64 // non-printable characters in the unencoded data.65 // http://stackoverflow.com/questions/1677644/detect-non-printable-characters-in-javascript66 isNonPrintable = /[\x00-\x09\x0E-\x1F]/.test(decoded);67 if (isNonPrintable) {68 nonPrintable[paramName] = true;69 return data;70 }71 return decoded;72 }73 });74 // Add a property to indicate when the decoded data contains75 // non-printable characters. Use the `$$` prefix so it's not76 // considered part of the data.77 decodedSecret.$$nonprintable = nonPrintable;78 return decodedSecret;79 };80 return {81 groupSecretsByType: groupSecretsByType,82 decodeSecretData: decodeSecretData83 };...
ui-key.js
Source: ui-key.js
1// ui-key.js -- Peteramati JavaScript library2// Peteramati is Copyright (c) 2006-2020 Eddie Kohler3// See LICENSE for open-source distribution terms4import { hasClass } from "./ui.js";5const key_map = {"Spacebar": " ", "Esc": "Escape"},6 charCode_map = {"9": "Tab", "13": "Enter", "27": "Escape"},7 keyCode_map = {8 "9": "Tab", "13": "Enter", "16": "ShiftLeft", "17": "ControlLeft",9 "18": "AltLeft", "20": "CapsLock", "27": "Escape", "33": "PageUp",10 "34": "PageDown", "37": "ArrowLeft", "38": "ArrowUp", "39": "ArrowRight",11 "40": "ArrowDown", "91": "OSLeft", "92": "OSRight", "93": "OSRight",12 "224": "OSLeft", "225": "AltRight"13 },14 nonprintable_map = {15 "Alt": 2,16 "AltLeft": 2,17 "AltRight": 2,18 "CapsLock": 2,19 "Control": 2,20 "ControlLeft": 2,21 "ControlRight": 2,22 "Meta": 2,23 "OSLeft": 2,24 "OSRight": 2,25 "Shift": 2,26 "ShiftLeft": 2,27 "ShiftRight": 2,28 "ArrowLeft": 1,29 "ArrowRight": 1,30 "ArrowUp": 1,31 "ArrowDown": 1,32 "Backspace": 1,33 "Enter": 1,34 "Escape": 1,35 "PageUp": 1,36 "PageDown": 1,37 "Tab": 138 };39export function event_key(evt) {40 let x;41 if (typeof evt === "string") {42 return evt;43 } else if ((x = evt.key) != null) {44 return key_map[x] || x;45 } else if ((x = evt.charCode)) {46 return charCode_map[x] || String.fromCharCode(x);47 } else if ((x = evt.keyCode)) {48 if (keyCode_map[x]) {49 return keyCode_map[x];50 } else if ((x >= 48 && x <= 57) || (x >= 65 && x <= 90)) {51 return String.fromCharCode(x);52 }53 } else {54 return "";55 }56}57event_key.printable = function (evt) {58 return !nonprintable_map[event_key(evt)]59 && (typeof evt === "string" || !(evt.ctrlKey || evt.metaKey));60};61event_key.is_modifier = function (evt) {62 return nonprintable_map[event_key(evt)] > 1;63};64event_key.is_default_a = function (evt, a) {65 return !evt.shiftKey && !evt.metaKey && !evt.ctrlKey66 && evt.button == 067 && (!a || !hasClass("ui", a));68};69export function event_modkey(evt) {70 return (evt.shiftKey ? 1 : 0) + (evt.ctrlKey ? 2 : 0) + (evt.altKey ? 4 : 0) + (evt.metaKey ? 8 : 0);71}72event_modkey.SHIFT = 1; // NB values matter73event_modkey.CTRL = 2;74event_modkey.ALT = 4;...
Url.js
Source: Url.js
1var UNICODE = '\\\\[0-9a-f]{1,6}(\\r\\n|[ \\n\\r\\t\\f])?';2var ESCAPE = '(' + UNICODE + '|\\\\[^\\n\\r\\f0-9a-fA-F])';3var NONPRINTABLE = '\u0000\u0008\u000b\u000e-\u001f\u007f';4var SAFE_URL = new RegExp('^(' + ESCAPE + '|[^\"\'\\(\\)\\\\\\s' + NONPRINTABLE + '])*$', 'i');5module.exports = function(node) {6 var value = node.value;7 if (value.type !== 'String') {8 return;9 }10 var quote = value.value[0];11 var url = value.value.substr(1, value.value.length - 2);12 // convert `\\` to `/`13 url = url.replace(/\\\\/g, '/');14 // remove quotes when safe15 // https://www.w3.org/TR/css-syntax-3/#url-unquoted-diagram16 if (SAFE_URL.test(url)) {17 node.value = {18 type: 'Raw',19 loc: node.value.loc,20 value: url21 };22 } else {23 // use double quotes if string has no double quotes24 // otherwise use original quotes25 // TODO: make better quote type selection26 node.value.value = url.indexOf('"') === -1 ? '"' + url + '"' : quote + url + quote;27 }...
Using AI Code Generation
1const { chromium } = require('playwright');2const fs = require('fs');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 const elementHandle = await page.$('input[name="q"]');8 await elementHandle.screenshot({ path: 'google.png' });9 const elementHandle2 = await page.$('input[name="btnK"]');10 await elementHandle2.screenshot({ path: 'google2.png' });11 await browser.close();12})();13const { chromium } = require('playwright');14const fs = require('fs');15(async () => {16 const browser = await chromium.launch({ headless: false });17 const context = await browser.newContext();18 const page = await context.newPage();19 const elementHandle = await page.$('input[name="q"]');20 await elementHandle.screenshot({ path: 'google.png' });21 const elementHandle2 = await page.$('input[name="btnK"]');22 await elementHandle2.screenshot({ path: 'google2.png' });23 await browser.close();24})();25const { chromium } = require('playwright');26const fs = require('fs');27(async () => {28 const browser = await chromium.launch({ headless: false });29 const context = await browser.newContext();30 const page = await context.newPage();31 const elementHandle = await page.$('input[name="q"]');32 await elementHandle.screenshot({ path: 'google.png' });33 const elementHandle2 = await page.$('input[name="btnK"]');34 await elementHandle2.screenshot({ path: 'google2.png' });35 await browser.close();36})();37const { chromium } = require('playwright');38const fs = require('fs');39(async () => {40 const browser = await chromium.launch({ headless: false });41 const context = await browser.newContext();
Using AI Code Generation
1const { chromium, devices } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.waitForTimeout(2000);7 await page.click('text=More information');8 await page.waitForTimeout(2000);
Using AI Code Generation
1const { nonprintable } = require('playwright/lib/internal/keyboard');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.keyboard.press(nonprintable('ArrowDown'));8 await browser.close();9})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 const element = await page.$('input');6 await element.press('ArrowUp');7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 const page = await browser.newPage();13 const element = await page.$('input');14 await element.nonprintable('ArrowUp');15 await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19 const browser = await chromium.launch();20 const page = await browser.newPage();21 const element = await page.$('input');22 await element.press('ArrowUp');23 await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27 const browser = await chromium.launch();28 const page = await browser.newPage();29 const element = await page.$('input');30 await element.nonprintable('ArrowUp');31 await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35 const browser = await chromium.launch();36 const page = await browser.newPage();37 const element = await page.$('input');38 await element.press('ArrowUp');39 await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43 const browser = await chromium.launch();44 const page = await browser.newPage();45 const element = await page.$('input');
Using AI Code Generation
1const { nonPrintable } = require('playwright/lib/client/keyboard');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.type('input[name="q"]', 'Playwright');8 await page.keyboard.press(nonPrintable.Enter);9 await page.screenshot({ path: `example.png` });10 await browser.close();11})();12const { chromium } = require('playwright');13(async () => {14 const browser = await chromium.launch();15 const context = await browser.newContext();16 const page = await context.newPage();17 await page.type('input[name="q"]', 'Playwright');18 await page.keyboard.press('Enter');19 await page.screenshot({ path: `example.png` });20 await browser.close();21})();22const { chromium } = require('playwright');23(async () => {24 const browser = await chromium.launch();25 const context = await browser.newContext();26 const page = await context.newPage();27 await page.type('input[name="q"]', 'Playwright');28 await page.keyboard.press('Enter');29 await page.screenshot({ path: `example.png` });30 await browser.close();31})();32const { chromium } = require('playwright');33(async () => {34 const browser = await chromium.launch();35 const context = await browser.newContext();36 const page = await context.newPage();37 await page.type('input[name="q"]', 'Playwright');38 await page.keyboard.press('Enter');39 await page.screenshot({ path: `example.png` });40 await browser.close();41})();42const { chromium } = require('playwright');43(async () => {44 const browser = await chromium.launch();45 const context = await browser.newContext();46 const page = await context.newPage();47 await page.type('input[name="q"]', 'Playwright');48 await page.keyboard.press('Enter');49 await page.screenshot({
Using AI Code Generation
1const { nonPrintable } = require('playwright-core/lib/internal/keyboard');2const { chromium } = require('playwright-core');3const fs = require('fs');4const path = require('path');5(async () => {6 const browser = await chromium.launch();7 const page = await browser.newPage();8 await page.type('input[title="Search"]', nonPrintable.Enter);9 await page.screenshot({ path: 'google.png' });10 await browser.close();11})();
Using AI Code Generation
1const { Playwright } = require('playwright-core');2const path = require('path');3const fs = require('fs');4const playwright = new Playwright({5 browsersPath: path.join(__dirname, 'browsers'),6 downloadsPath: path.join(__dirname, 'downloads'),7 driversPath: path.join(__dirname, 'drivers'),8});9(async () => {10 const browser = await playwright.chromium.launch({ headless: false });11 const context = await browser.newContext();12 const page = await context.newPage();13 await page.route('**/*', route => {14 if (route.request().url().endsWith('png')) {15 console.log(route.request().url());16 route.fulfill({17 path: path.join(__dirname, 'test.png'),18 headers: {19 },20 });21 } else {22 route.continue();23 }24 });25 await page.screenshot({ path: path.join(__dirname, 'test.png') });26 await browser.close();27})();28When I change the route.fulfill() to route.fulfill({body: fs.readFileSync(path.join(__dirname, 'test.png'))}), the test.png file is created, but the content of the file is not the image, it is the string "data:image
Using AI Code Generation
1const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');2console.log(nonprintable);3const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');4console.log(nonprintable);5const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');6console.log(nonprintable);7const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');8console.log(nonprintable);9const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');10console.log(nonprintable);11const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');12console.log(nonprintable);13const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');14console.log(nonprintable);15const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');16console.log(nonprintable);17const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');18console.log(nonprintable);19const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');20console.log(nonprintable);21const { nonprintable } = require('@playwright/test/lib/server/keyboardLayouts');22console.log(nonprintable);23const {
Using AI Code Generation
1const {chromium} = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const ariaLabel = await page.$eval('#ex1 button', el => el.getAttribute('aria-label'));7 console.log(ariaLabel);8 await browser.close();9})();
Jest + Playwright - Test callbacks of event-based DOM library
firefox browser does not start in playwright
Is it possible to get the selector from a locator object in playwright?
How to run a list of test suites in a single file concurrently in jest?
Running Playwright in Azure Function
firefox browser does not start in playwright
This question is quite close to a "need more focus" question. But let's try to give it some focus:
Does Playwright has access to the cPicker object on the page? Does it has access to the window object?
Yes, you can access both cPicker and the window object inside an evaluate call.
Should I trigger the events from the HTML file itself, and in the callbacks, print in the DOM the result, in some dummy-element, and then infer from that dummy element text that the callbacks fired?
Exactly, or you can assign values to a javascript variable:
const cPicker = new ColorPicker({
onClickOutside(e){
},
onInput(color){
window['color'] = color;
},
onChange(color){
window['result'] = color;
}
})
And then
it('Should call all callbacks with correct arguments', async() => {
await page.goto(`http://localhost:5000/tests/visual/basic.html`, {waitUntil:'load'})
// Wait until the next frame
await page.evaluate(() => new Promise(requestAnimationFrame))
// Act
// Assert
const result = await page.evaluate(() => window['color']);
// Check the value
})
Check out the latest blogs from LambdaTest on this topic:
Native apps are developed specifically for one platform. Hence they are fast and deliver superior performance. They can be downloaded from various app stores and are not accessible through browsers.
One of the essential parts when performing automated UI testing, whether using Selenium or another framework, is identifying the correct web elements the tests will interact with. However, if the web elements are not located correctly, you might get NoSuchElementException in Selenium. This would cause a false negative result because we won’t get to the actual functionality check. Instead, our test will fail simply because it failed to interact with the correct element.
Smartphones have changed the way humans interact with technology. Be it travel, fitness, lifestyle, video games, or even services, it’s all just a few touches away (quite literally so). We only need to look at the growing throngs of smartphone or tablet users vs. desktop users to grasp this reality.
As part of one of my consulting efforts, I worked with a mid-sized company that was looking to move toward a more agile manner of developing software. As with any shift in work style, there is some bewilderment and, for some, considerable anxiety. People are being challenged to leave their comfort zones and embrace a continuously changing, dynamic working environment. And, dare I say it, testing may be the most ‘disturbed’ of the software roles in agile development.
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!