Best JavaScript code snippet using best
TreeDict.js
Source:TreeDict.js
1/**2 * æ ç¶åå
¸ï¼å éä¸æèå读åé度3 * @class TreeDict4 * @see <a href="https://github.com/xueduany/KitJs/blob/master/KitJs/src/js/TreeDict.js">Source code</a>5 * @modify6 * 2012/04/097 * æ¸
æä¼åæ³å°çï¼å¦æéå°âå京âåâå京å¸âï¼è¿ä¸¤ä¸ªä½ä¸ºkeyåå
¥åå
¸ï¼æ¶ï¼æç
§ç°å¨çé»è¾ï¼å京å¸ä¼æå京çæï¼8 * ç°å¨æ¹ä¸ºå¯¹äºååç¼çkeyï¼å å
¥ç»ææ è®°ä½ä¸ºåºåï¼è¿æ ·æ¶é´åå¨åå
¸éé¢çæ¯"å京endSing"åå京å¸endSignï¼è¿æ ·å°±å¯ä»¥åºåå¼äº9 */10var TreeDict = function(config) {11 var me = this;12 me.config = $kit.join(arguments.callee.defaultConfig, config);13 me.size = 0;14 me.deep = me.config.deep;15 me.data = {};16}17/**18 * @member19 * @enum20 */21TreeDict.defaultConfig = {22 deep : 10, //åµå¥æ·±åº¦ï¼æ¤åæ°å½±åè¯å
¸å
å对象大å°ï¼ä¹å½±åsearchç´¢å¼æ§è½23 data : undefined,24 endSign : '$end$'//é¿å
"å京"ä½ä¸ºkey被"å京å¸"è¦çæï¼ç°å¼ç¨ç»ææ è®°æ¦å¿µï¼ä»¥åºå«abåabcè¿æ ·çå符25}26TreeDict.prototype = {27 constructor : TreeDict,28 /**29 * å¤ææ¯å¦åå¨30 * @param {String}31 * @return {Boolean}32 */33 hs : function(key) {34 var key = key || null, me = this;35 if(key == null) {36 var beginIndex = 0, recurDeep = 0, //37 lookfor = me.data, index, lastLookfor, find;38 while(beginIndex < key.length) {39 if(recurDeep < me.deep - 1) {40 index = key.substring(beginIndex, beginIndex + 1);41 find = lookfor[index];42 } else {43 index = key.substring(beginIndex);44 find = lookfor[index];45 }46 if($kit.isEmpty(find)) {47 return false;48 } else {49 if(beginIndex == key.length - 1 || recurDeep == me.deep - 1) {50 return true;51 }52 }53 lookfor = find;54 beginIndex++;55 recurDeep++;56 }57 return false;58 }59 },60 /**61 * æ·»å 62 * @param {String}63 * @param {String}64 */65 ad : function(key, value) {66 var value = value || null;67 var key = key || null;68 var me = this;69 if(key == null || value == null) {70 return;71 }72 var beginIndex = 0, recurDeep = 0, //73 lookfor = me.data, index, lastLookfor, find;74 while(beginIndex < key.length) {75 if(recurDeep < me.deep - 1) {76 index = key.substring(beginIndex, beginIndex + 1);77 find = lookfor[index];78 } else {79 index = key.substring(beginIndex);80 find = lookfor[index];81 }82 if($kit.isEmpty(find)) {//å¦ææ¾ä¸å°keyäº83 if(beginIndex == key.length - 1 || recurDeep == me.deep - 1) {84 lookfor[index] = {};85 lookfor[index][me.config.endSign] = value;86 find = lookfor[index];87 } else {88 find = lookfor[index] = {};89 }90 } else {91 if(beginIndex == key.length - 1 || recurDeep == me.deep - 1) {92 find[me.config.endSign] = value;93 }94 }95 lookfor = find;96 beginIndex++;97 recurDeep++;98 }99 },100 /**101 * å é¤102 * @param {String}103 */104 rm : function(key) {105 var key = key || null;106 var me = this;107 if(key == null) {108 return;109 }110 var beginIndex = 0, recurDeep = 0, //111 lookfor = me.data, index, lastLookfor, find;112 while(beginIndex < key.length) {113 if(recurDeep < me.deep - 1) {114 index = key.substring(beginIndex, beginIndex + 1);115 find = lookfor[index];116 } else {117 index = key.substring(beginIndex);118 find = lookfor[index];119 }120 if($kit.isEmpty(find)) {121 return false;122 } else {123 if(beginIndex == key.length - 1 || recurDeep == me.deep - 1) {124 delete lookfor[index][me.config.endSign];125 //æ没å«çç´¢å¼ï¼æ²¡æå°±æ©èé¤æ ¹!!!126 var deleteIndex = false;127 for(var p in lookfor[index]) {128 deleteIndex = true;129 break;130 }131 if(deleteIndex) {132 delete lookfor[index];133 }134 }135 }136 lookfor = find;137 beginIndex++;138 recurDeep++;139 }140 },141 /**142 * åæ¾æ°æ®æ»æ°143 * @return {Number}144 */145 size : function() {146 this.size = this.count(0, this.data);147 return this.size;148 },149 count : function(size, o) {150 var me = this;151 size = size || 0;152 for(var p in o) {153 if(o[p][me.config.endSign]) {154 size++;155 } else {156 size += this.count(size, o[p]);157 }158 }159 return size;160 },161 /**162 * ä»åå
¸ä¸ååºç¬¦åkeyçvalueå¼163 * @param {String}164 * @return {String}165 */166 get : function(key) {167 var value = value || null;168 var key = key || null;169 var me = this;170 if(key == null) {171 return;172 }173 var beginIndex = 0, recurDeep = 0, //174 lookfor = me.data, index, lastLookfor, find;175 while(beginIndex < key.length) {176 if(recurDeep < me.deep - 1) {177 index = key.substring(beginIndex, beginIndex + 1);178 find = lookfor[index];179 } else {180 index = key.substring(beginIndex);181 find = lookfor[index];182 }183 if($kit.isEmpty(find)) {//å¦ææ¾ä¸å°keyäº184 return null;185 } else {186 if(beginIndex == key.length - 1 || recurDeep == me.deep - 1) {187 return find[me.config.endSign];188 }189 }190 lookfor = find;191 beginIndex++;192 recurDeep++;193 }194 return null;195 },196 /**197 * æé¦å符å¹é
ååæ¥è¯¢ï¼è¿å198 * [{key: 'key', value: 'value'}, {key: 'key', value: 'value'}]æ ¼å¼æ°ç»199 * @param {String}200 * @return {Array}201 */202 search : function(key) {203 var value = value || null;204 var key = key || null;205 var me = this;206 if(key == null || key == '') {207 var re = [];208 me.travel(me.data, re);209 return re;210 }211 var beginIndex = 0, recurDeep = 0, //212 lookfor = me.data, index, lastLookfor, find;213 var keyArray = [];214 while(beginIndex < key.length) {215 if(recurDeep < me.deep - 1) {216 index = key.substring(beginIndex, beginIndex + 1);217 find = lookfor[index];218 } else {219 index = key.substring(beginIndex);220 find = lookfor[index];221 }222 if($kit.isEmpty(find)) {//å¦ææ¾ä¸å°keyäº223 return null;224 } else {225 keyArray.push(index);226 if(beginIndex == key.length - 1 || recurDeep == me.deep - 1) {227 break;228 }229 }230 lookfor = find;231 beginIndex++;232 recurDeep++;233 }234 var re = [];235 var beginData;236 beginData = me.data[keyArray[0]];237 for(var i = 1; i < keyArray.length; i++) {238 beginData = beginData[keyArray[i]];239 }240 me.travel(beginData, re, keyArray.join(''));241 return re;242 },243 /**244 * @private245 */246 travel : function(tree, array, key, currentKey) {247 var me = this;248 if(tree == null) {249 return;250 }251 key = key || '';252 array = array || [];253 if(tree[me.config.endSign]) {254 array.push({255 key : key,256 value : tree[me.config.endSign]257 });258 }259 for(var k in tree) {260 if(k != me.config.endSign) {261 me.travel(tree[k], array, key + k, k);262 }263 }264 }265};266/**267 * @class $kit.TreeDict268 * @extends TreeDict269 */
...
xcode-refactor.js
Source:xcode-refactor.js
1const fs = require('fs');2const path = require('path');3const DIRECTORIES = ['BackgroundGeolocation', 'BackgroundGeolocationTests'];4const PBX_PROJ = path.join('BackgroundGeolocation.xcodeproj', 'project.pbxproj');5const PREFIX = 'MAUR';6const FILENAME_INCLUDE_CRITERIA = [7 /\.h$/,8 /\.m$/,9];10const FILENAME_EXCLUDE_CRITERIA = [11 RegExp(`^${PREFIX}`), // file is already prefixed12 /^(?=[A-Z]{2,})((?!SQL)).*/, //match leading 2 capital letters except SQL13 /^Reachability/,14 /^CocoaLumberjack/,15 /^Util/16];17const IMPORT_REGEXP = /\s*#import\s?\"(\w+\.[a-z]?)\"/g;18// https://stackoverflow.com/a/6969486/389661619function escapeRegExp(str) {20 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");21}22let files = [].concat.apply([], DIRECTORIES.map(dir => fs.readdirSync(dir)23 .filter(fileName => {24 if (!FILENAME_INCLUDE_CRITERIA.some(regexp => regexp.test(fileName))) {25 return false;26 }27 if (!FILENAME_EXCLUDE_CRITERIA.some(regexp => regexp.test(fileName))) {28 return true;29 }30 return false;31 })32 .map(fileName => [dir, fileName])33));34const refactorTable = files.reduce((memo, [dir, fileName]) => {35 memo[fileName] = `${PREFIX}${fileName}`;36 return memo;37}, {});38const objInstances = Object.entries(refactorTable).reduce((memo, [fileName, newFileName]) => {39 const [instanceName] = fileName.split('.');40 const [newInstanceName] = newFileName.split('.');41 memo[instanceName] = newInstanceName;42 return memo;43}, {});44const ref = files.map(([dir, fileName]) => {45 let matches;46 const imports = [];47 const [file, extension = ''] = fileName.split('.');48 const fileComment = extension ? `${file}_${extension}` : file;49 const oldPath = path.join(dir, fileName);50 const newPath = path.join(dir, refactorTable[fileName]);51 let content = fs.readFileSync(oldPath, 'utf8');52 // log imports to be returned from function53 while ((matches = IMPORT_REGEXP.exec(content)) !== null) {54 const [match, p1] = matches;55 imports.push(p1);56 }57 // replace imports58 content = content.replace(IMPORT_REGEXP, (match, fileName) => {59 const beginIndex = match.indexOf(fileName);60 const begin = match.substring(0, beginIndex);61 const end = match.substring(beginIndex + fileName.length);62 const refactoredFileName = refactorTable[fileName] || fileName;63 return `${begin}${refactoredFileName}${end}`;64 });65 /*66 replace class name in comment67 eg:68 // BackgroundGeolocationFacade.h69 */70 content = content.replace(RegExp(`\/\/\\s*(${escapeRegExp(fileName)})`), (match, p1) => {71 const beginIndex = match.indexOf(p1);72 const begin = match.substring(0, beginIndex);73 const end = match.substring(beginIndex + p1.length);74 return `${begin}${PREFIX}${p1}${end}`;75 });76 // replace ifdefs and ifndef77 content = content.replace(RegExp(`#ifndef\\s*(${escapeRegExp(fileComment)})`), (match, p1) => {78 const beginIndex = match.indexOf(p1);79 const begin = match.substring(0, beginIndex);80 const end = match.substring(beginIndex + p1.length);81 return `${begin}${PREFIX}${p1}${end}`;82 });83 // replace define84 content = content.replace(RegExp(`#define\\s*(${escapeRegExp(fileComment)})`), (match, p1) => {85 const beginIndex = match.indexOf(p1);86 const begin = match.substring(0, beginIndex);87 const end = match.substring(beginIndex + p1.length);88 return `${begin}${PREFIX}${p1}${end}`;89 });90 // replace endif91 content = content.replace(RegExp(`#endif\\s*\\/\\*\\s*(${escapeRegExp(fileComment)})\\s*\\*\\/`), (match, p1) => {92 const beginIndex = match.indexOf(p1);93 const begin = match.substring(0, beginIndex);94 const end = match.substring(beginIndex + p1.length);95 return `${begin}${PREFIX}${p1}${end}`;96 });97 // replace interface98 content = content.replace(RegExp(`\\s*@interface\\s*(${escapeRegExp(file)})\\s*(:\\s*(\\w+)(<\\w+>)?)?`), (match, p1, p2, p3) => {99 if (p3) {100 const beginIndex = match.indexOf(p1);101 const begin = match.substring(0, beginIndex);102 const protocolIndex = match.indexOf(p3);103 const end = match.substring(protocolIndex + p3.length);104 return [105 `${begin}${PREFIX}${p1}`,106 `${match.substring(beginIndex + p1.length, protocolIndex)}`,107 `${objInstances[p3]||p3}`,108 `${end}`109 ].join('');110 } else {111 const beginIndex = match.indexOf(p1);112 const begin = match.substring(0, beginIndex);113 const end = match.substring(beginIndex + p1.length); 114 return `${begin}${PREFIX}${p1}${end}`;115 }116 });117 // replace implementation118 // TODO: replace protocol too119 content = content.replace(RegExp(`\\s*@implementation\\s*(${escapeRegExp(file)})`), (match, p1) => {120 let beginIndex = match.indexOf(p1);121 let begin = match.substring(0, beginIndex);122 let end = match.substring(beginIndex + p1.length);123 return `${begin}${PREFIX}${p1}${end}`;124 });125 // replace vars126 Object.entries(objInstances).forEach(([oldName, newName]) => {127 content = content.replace(RegExp(`\\b(${escapeRegExp(oldName)})\\s*(<\\w+>)?\\s*\\*`, 'g'), (match, p1) => {128 const beginIndex = match.indexOf(p1);129 const begin = match.substring(0, beginIndex);130 const end = match.substring(beginIndex + p1.length);131 return `${begin}${newName}${end}`;132 }); 133 });134 // replace static method calls135 Object.entries(objInstances).forEach(([oldName, newName]) => {136 content = content.replace(RegExp(`\\[(${escapeRegExp(oldName)})\\s+.*\\]`, 'g'), (match, p1) => {137 const beginIndex = match.indexOf(p1);138 const begin = match.substring(0, beginIndex);139 const end = match.substring(beginIndex + p1.length);140 return `${begin}${newName}${end}`;141 }); 142 });143 fs.renameSync(oldPath, newPath);144 fs.writeFileSync(newPath, content);145 return {146 oldPath,147 newPath,148 imports,149 newImports: imports.map(imp => refactorTable[imp]||imp)150 }151});152let pbxProj = fs.readFileSync(PBX_PROJ, 'utf8');153Object.keys(refactorTable).forEach(fileName => {154 pbxProj = pbxProj.replace(RegExp(`\\b(${escapeRegExp(fileName)})`, 'g'), (match, fileName) => {155 const beginIndex = match.indexOf(fileName);156 const begin = match.substring(0, beginIndex);157 const end = match.substring(beginIndex + fileName.length);158 const refactoredFileName = refactorTable[fileName];159 return `${begin}${refactoredFileName}${end}`;160 });161});162fs.writeFileSync(PBX_PROJ, pbxProj);...
Using AI Code Generation
1var BestMatch = require('./bestMatch.js');2var bestMatch = new BestMatch();3var text = 'The quick brown fox jumps over the lazy dog';4var substring = 'fox';5var index = bestMatch.beginIndex(text, substring);6class BestMatch {7 beginIndex(text, substring) {8 var textLength = text.length;9 var substringLength = substring.length;10 var index = 0;11 var found = false;12 var i = 0;13 while (index < textLength && !found) {14 if (text[index] == substring[0]) {15 i = 1;16 while (i < substringLength && text[index + i] == substring[i]) {17 i++;18 }19 if (i == substringLength) {20 found = true;21 }22 }23 index++;24 }25 if (found) {26 return index - 1;27 } else {28 return -1;29 }30 }31}32module.exports = BestMatch;
Using AI Code Generation
1var BestMatch = require('./BestMatch.js');2var bestMatch = new BestMatch();3var str = "The quick brown fox jumps over the lazy dog.";4console.log(bestMatch.beginIndex(str, "fox"));5console.log(bestMatch.beginIndex(str, "dog"));6console.log(bestMatch.beginIndex(str, "cat"));7console.log(bestMatch.beginIndex(str, "fox", 10));8console.log(bestMatch.beginIndex(str, "fox", 40));9console.log(bestMatch.beginIndex(str, "fox", 41));10console.log(bestMatch.beginIndex(str, "fox", 42));11console.log(bestMatch.beginIndex(str, "fox", 43));12console.log(bestMatch.beginIndex(str, "fox", 44));13console.log(bestMatch.beginIndex(str, "fox", 45));14console.log(bestMatch.beginIndex(str, "fox", 46));15console.log(bestMatch.beginIndex(str, "fox", 47));16console.log(bestMatch.beginIndex(str, "fox", 48));17console.log(bestMatch.beginIndex(str, "fox", 49));18console.log(bestMatch.beginIndex(str, "fox", 50));19console.log(bestMatch.beginIndex(str, "fox", 51));20console.log(bestMatch.beginIndex(str, "fox", 52));21console.log(bestMatch.beginIndex(str, "fox", 53));22console.log(bestMatch.beginIndex(str, "fox", 54));23console.log(bestMatch.beginIndex(str, "fox", 55));24console.log(bestMatch.beginIndex(str, "fox", 56));25console.log(bestMatch.beginIndex(str, "fox", 57));26console.log(bestMatch.beginIndex(str, "fox", 58));27console.log(bestMatch.beginIndex(str, "fox", 59));28console.log(bestMatch.beginIndex(str, "fox", 60));29console.log(bestMatch.beginIndex(str, "fox", 61));30console.log(bestMatch.beginIndex(str, "fox", 62));31console.log(bestMatch.beginIndex(str, "fox", 63));32console.log(bestMatch.beginIndex(str, "fox", 64));33console.log(bestMatch.beginIndex(str, "fox", 65));34console.log(bestMatch.beginIndex(str, "fox", 66));35console.log(bestMatch.beginIndex(str, "fox", 67));36console.log(bestMatch.beginIndex(str, "fox", 68));37console.log(bestMatch.beginIndex(str, "fox",
Using AI Code Generation
1var BestMatch = require("./BestMatch.js");2var bestMatch = new BestMatch();3var text = "abcde";4var pattern = "cde";5console.log("Best Match Index: " + bestMatch.beginIndex(text, pattern));6var BestMatch = function() {7 this.beginIndex = function(text, pattern) {8 var i = 0;9 var j = 0;10 while (i < text.length && j < pattern.length) {11 if (text.charAt(i) == pattern.charAt(j)) {12 i++;13 j++;14 } else {15 i = i - j + 1;16 j = 0;17 }18 }19 if (j == pattern.length) {20 return i - j;21 } else {22 return -1;23 }24 };25};26module.exports = BestMatch;
Using AI Code Generation
1var BestMatch = require('./bestMatch.js');2var bm = new BestMatch();3var str = "abcd";4var sub = "cd";5var index = bm.beginIndex(str, sub);6console.log("beginIndex: " + index);
Using AI Code Generation
1var BestMatch = require('./lib/best_match.js');2var bestMatch = new BestMatch();3var str = "hello";4var index = bestMatch.beginIndex("hello world", str);5var BestMatch = require('./lib/best_match.js');6var bestMatch = new BestMatch();7var str = "world";8var index = bestMatch.endIndex("hello world", str);9var BestMatch = require('./lib/best_match.js');10var bestMatch = new BestMatch();11var str = "hello world";12var index = bestMatch.bestMatch("hello world", str);13var BestMatch = require('./lib/best_match.js');14var bestMatch = new BestMatch();15var str = "hello";16var index = bestMatch.indexOf("hello world", str);17var BestMatch = require('./lib/best_match.js');18var bestMatch = new BestMatch();19var str = "world";20var index = bestMatch.lastIndexOf("hello world", str);21var BestMatch = require('./lib/best_match.js');22var bestMatch = new BestMatch();23var str = "hello world";24var index = bestMatch.bestMatch("hello world", str);25var BestMatch = require('./lib/best_match.js');26var bestMatch = new BestMatch();27var str = "hello world";28var index = bestMatch.bestMatch("hello world", str);29var BestMatch = require('./lib/best_match.js');30var bestMatch = new BestMatch();31var str = "hello world";32var index = bestMatch.bestMatch("
Using AI Code Generation
1var BestMatchFinder = require('./BestMatchFinder');2var bestMatchFinder = new BestMatchFinder();3var input = "This is a test string to test the functionality of the BestMatchFinder class";4var result = bestMatchFinder.beginIndex(input, "test");5console.log(result);6function BestMatchFinder() {7}8BestMatchFinder.prototype.beginIndex = function(input, subString) {9 var result = input.indexOf(subString);10 return result;11};12module.exports = BestMatchFinder;13describe("BestMatchFinder", function() {14 var bestMatchFinder;15 beforeEach(function() {16 bestMatchFinder = new BestMatchFinder();17 });18 it("should return 10 for the beginIndex of 'test' in the string 'This is a test string to test the functionality of the BestMatchFinder class'", function() {19 var input = "This is a test string to test the functionality of the BestMatchFinder class";20 var subString = "test";21 var result = bestMatchFinder.beginIndex(input, subString);22 expect(result).toBe(10);23 });24});
Using AI Code Generation
1var BestMatch = require('./bestMatch');2var bm = new BestMatch();3var text = 'The quick brown fox jumped over the lazy dog';4var string = 'fox jumped';5var index = bm.beginIndex(text, string);6console.log('The best match of ' + string + ' in ' + text + ' is ' + index);7function BestMatch() {8}9BestMatch.prototype.beginIndex = function(text, string) {10 var index = text.indexOf(string);11 var bestMatch = index;12 var bestMatchLength = string.length;13 while (index > -1) {14 var length = this.matchLength(text, string, index);15 if (length > bestMatchLength) {16 bestMatch = index;17 bestMatchLength = length;18 }19 index = text.indexOf(string, index + 1);20 }21 return bestMatch;22}23BestMatch.prototype.matchLength = function(text, string, index) {24 var length = 0;25 while (text.charAt(index) == string.charAt(index)) {26 length++;27 index++;28 }29 return length;30}31module.exports = BestMatch;
Using AI Code Generation
1var BestMatch = require('./BestMatch');2var bm = new BestMatch();3var arr = ['cat', 'dog', 'cow', 'mouse', 'goat', 'rat'];4var str = 'caw';5console.log(bm.beginIndex(arr, str));6function BestMatch() {7 this.beginIndex = function(arr, str) {8 var index = -1;9 var max = 0;10 for (var i = 0; i < arr.length; i++) {11 var count = 0;12 for (var j = 0; j < str.length; j++) {13 if (str[j] == arr[i][j]) {14 count++;15 }
Using AI Code Generation
1var bestMatchObj = new BestMatch();2var input = "Java";3var result = bestMatchObj.beginIndex(input);4console.log(result);5var BestMatch = function() {6var array = ['Java', 'JavaScript', 'C', 'C++', 'C#', 'Python', 'Ruby', 'PHP', 'Perl', 'Scala', 'Swift', 'Groovy'];7this.beginIndex = function (input) {8var result = [];9for (var i = 0; i < array.length; i++) {10if (array[i].indexOf(input) === 0) {11result.push(array[i]);12}13}14return result;15}16}17var bestMatchObj = new BestMatch();18var input = "Java";19var result = bestMatchObj.endIndex(input);20console.log(result);21var BestMatch = function() {22var array = ['Java', 'JavaScript', 'C', 'C++', 'C#', 'Python', 'Ruby', 'PHP', 'Perl', 'Scala', 'Swift', 'Groovy'];23this.endIndex = function (input) {24var result = [];25for (var i = 0; i < array.length; i++) {26if (array[i].indexOf(input) === array[i].length - input.length) {27result.push(array[i]);28}29}30return result;31}32}33var bestMatchObj = new BestMatch();34var input = "Java";35var result = bestMatchObj.partialIndex(input);36console.log(result);37var BestMatch = function() {38var array = ['Java', 'JavaScript', 'C', 'C++', 'C#', 'Python', 'Ruby', 'PHP', 'Perl', 'Scala', 'Swift', 'Groovy'];
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!