Best Karate code snippet using com.intuit.karate.http.RequestHandler
Source:Main.java
...26import com.intuit.karate.core.RuntimeHookFactory;27import com.intuit.karate.debug.DapServer;28import com.intuit.karate.formats.PostmanConverter;29import com.intuit.karate.http.HttpServer;30import com.intuit.karate.http.RequestHandler;31import com.intuit.karate.http.ServerConfig;32import com.intuit.karate.http.SslContextFactory;33import com.intuit.karate.job.JobExecutor;34import com.intuit.karate.resource.ResourceUtils;35import com.intuit.karate.shell.Command;36import java.io.File;37import java.lang.reflect.Method;38import java.util.ArrayList;39import java.util.Collection;40import java.util.Collections;41import java.util.List;42import java.util.concurrent.Callable;43import java.util.regex.Matcher;44import java.util.regex.Pattern;45import java.util.stream.Collectors;46import org.slf4j.ILoggerFactory;47import org.slf4j.LoggerFactory;48import picocli.CommandLine;49import picocli.CommandLine.Option;50import picocli.CommandLine.Parameters;51/**52 *53 * @author pthomas354 */55public class Main implements Callable<Void> {56 private static final String LOGBACK_CONFIG = "logback.configurationFile";57 private static org.slf4j.Logger logger;58 @Option(names = {"-h", "--help"}, usageHelp = true, description = "display this help message")59 boolean help;60 @Parameters(split = "$", description = "one or more tests (features) or search-paths to run")61 List<String> paths;62 @Option(names = {"-m", "--mock"}, description = "mock server file")63 File mock;64 @Option(names = {"-p", "--port"}, description = "server port (default 8080)")65 int port = 8080;66 @Option(names = {"-W", "--watch"}, description = "watch (and hot-reload) mock server file for changes")67 boolean watch; 68 @Option(names = {"-S", "--serve"}, description = "app server using --workdir (experimental)")69 boolean serve;70 @Option(names = {"-s", "--ssl"}, description = "use ssl / https, will use '"71 + SslContextFactory.DEFAULT_CERT_NAME + "' and '" + SslContextFactory.DEFAULT_KEY_NAME72 + "' if they exist in the working directory, or generate them")73 boolean ssl;74 @Option(names = {"-c", "--cert"}, description = "ssl certificate (default: " + SslContextFactory.DEFAULT_CERT_NAME + ")")75 File cert;76 @Option(names = {"-k", "--key"}, description = "ssl private key (default: " + SslContextFactory.DEFAULT_KEY_NAME + ")")77 File key;78 @Option(names = {"-t", "--tags"}, description = "cucumber tags - e.g. '@smoke,~@ignore'")79 List<String> tags;80 @Option(names = {"-T", "--threads"}, description = "number of threads when running tests")81 int threads = 1;82 @Option(names = {"-o", "--output"}, description = "directory where logs and reports are output (default 'target')")83 String output = FileUtils.getBuildDir();84 @Option(names = {"-f", "--format"}, split = ",", description = "comma separate report output formats. tilde excludes the output report. html report is included by default unless it's negated."85 + "e.g. '-f json,cucumber:json,junit:xml. Possible values [html: Karate HTML, json: Karate JSON, cucumber:json: Cucumber JSON, junit:xml: JUnit XML]")86 List<String> formats;87 @Option(names = {"-n", "--name"}, description = "scenario name")88 String name;89 @Option(names = {"-e", "--env"}, description = "value of 'karate.env'")90 String env;91 @Option(names = {"-w", "--workdir"}, description = "working directory, defaults to '.'")92 File workingDir = FileUtils.WORKING_DIR;93 @Option(names = {"-g", "--configdir"}, description = "directory where 'karate-config.js' is expected (default 'classpath:' or <workingdir>)")94 String configDir;95 @Option(names = {"-C", "--clean"}, description = "clean output directory")96 boolean clean;97 @Option(names = {"-d", "--debug"}, arity = "0..1", defaultValue = "-1", fallbackValue = "0",98 description = "debug mode (optional port else dynamically chosen)")99 int debugPort;100 @Option(names = {"-D", "--dryrun"}, description = "dry run, generate html reports only")101 boolean dryRun;102 @Option(names = {"-j", "--jobserver"}, description = "job server url")103 String jobServerUrl;104 @Option(names = {"-i", "--import"}, description = "import and convert a file")105 String importFile;106 @Option(names = {"-H", "--hook"}, split = ",", description = "class name of a RuntimeHook (or RuntimeHookFactory) to add")107 List<String> hookFactoryClassNames;108 //==========================================================================109 //110 public void addPath(String path) {111 if (paths == null) {112 paths = new ArrayList();113 }114 paths.add(path);115 }116 public void setPaths(List<String> paths) {117 this.paths = paths;118 }119 public List<String> getPaths() {120 return paths;121 }122 public List<String> getTags() {123 return tags;124 }125 public int getThreads() {126 return threads;127 }128 public String getName() {129 return name;130 }131 public void setName(String name) {132 this.name = name;133 }134 public boolean isOutputHtmlReport() {135 return formats == null ? true : !formats.contains("~html");136 }137 public boolean isOutputCucumberJson() {138 return formats == null ? false : formats.contains("cucumber:json");139 }140 public boolean isOutputJunitXml() {141 return formats == null ? false : formats.contains("junit:xml");142 }143 public String getEnv() {144 return env;145 }146 public void setEnv(String env) {147 this.env = env;148 }149 public String getConfigDir() {150 return configDir;151 }152 public void setConfigDir(String configDir) {153 this.configDir = configDir;154 }155 public static Main parseKarateOptions(String line) {156 String[] args = Command.tokenize(line);157 return CommandLine.populateCommand(new Main(), args);158 }159 // matches ( -X XXX )* (XXX)160 private static final Pattern CLI_ARGS = Pattern.compile("(\\s*-{1,2}\\w\\s\\S*\\s*)*(.*)$");161 // adds double-quotes to last positional parameter (path) in case it contains white-spaces and un-quoted162 // only if line contains just one positional parameter (path) and it is the last one in line.163 // needed for intelli-j and vs-code generated cli invocations164 public static Main parseKarateOptionsAndQuotePath(String line) {165 Matcher matcher = CLI_ARGS.matcher(line);166 if (matcher.find()) {167 String path = matcher.group(2).trim();168 if (path.contains(" ")) {169 // unquote if necessary170 String options = line.substring(0, line.lastIndexOf(path));171 path = path.replaceAll("^\"|^'|\"$|\'$", "");172 line = String.format("%s \"%s\"", options, path);173 }174 }175 return Main.parseKarateOptions(line.trim());176 }177 public Collection<RuntimeHook> createHooks() {178 if (this.hookFactoryClassNames != null) {179 return this.hookFactoryClassNames.stream()180 .map(c -> createHook(c)).collect(Collectors.toList());181 }182 return Collections.emptyList();183 }184 private RuntimeHook createHook(String hookClassName) {185 if (hookClassName != null) {186 try {187 Class hookClass = Class.forName(hookClassName);188 if (RuntimeHookFactory.class.isAssignableFrom(hookClass)) {189 return ((RuntimeHookFactory) hookClass.newInstance()).create();190 } else if (RuntimeHook.class.isAssignableFrom(hookClass)) {191 return (RuntimeHook) hookClass.newInstance();192 }193 } catch (Exception e) {194 logger.error("error instantiating RuntimeHook: {}", hookClassName, e);195 }196 logger.error("provided hook / class is not a RuntimeHook or RuntimeHookFactory: {}", hookClassName);197 }198 return null;199 }200 public static void main(String[] args) {201 boolean isClean = false;202 boolean isOutputArg = false;203 String outputDir = FileUtils.getBuildDir();204 // hack to manually extract the output dir arg to redirect karate.log if needed205 for (String s : args) {206 if (isOutputArg) {207 outputDir = s;208 isOutputArg = false;209 }210 if (s.startsWith("-o") || s.startsWith("--output")) {211 int pos = s.indexOf('=');212 if (pos != -1) {213 outputDir = s.substring(pos + 1);214 } else {215 isOutputArg = true;216 }217 }218 if (s.startsWith("-C") || s.startsWith("--clean")) {219 isClean = true;220 }221 }222 if (isClean) {223 // ensure karate.log is not held open which will prevent224 // a graceful delete of "target" especially on windows225 System.setProperty(LOGBACK_CONFIG, "logback-nofile.xml");226 } else {227 System.setProperty(Constants.KARATE_OUTPUT_DIR, outputDir);228 // ensure we init logback before anything else229 String logbackConfig = System.getProperty(LOGBACK_CONFIG);230 if (StringUtils.isBlank(logbackConfig)) {231 File logbackXml = ResourceUtils.classPathOrFile("logback.xml");232 File logbackTest = ResourceUtils.classPathOrFile("logback-test.xml");233 if (logbackTest != null) {234 System.setProperty(LOGBACK_CONFIG, "logback-test.xml");235 } else if (logbackXml != null) {236 System.setProperty(LOGBACK_CONFIG, "logback.xml");237 } else {238 System.setProperty(LOGBACK_CONFIG, "logback-fatjar.xml");239 }240 }241 }242 resetLoggerConfig();243 logger = LoggerFactory.getLogger("com.intuit.karate");244 logger.info("Karate version: {}", FileUtils.KARATE_VERSION);245 CommandLine cmd = new CommandLine(new Main());246 int returnCode = cmd.execute(args);247 System.exit(returnCode);248 }249 private static void resetLoggerConfig() {250 ILoggerFactory factory = LoggerFactory.getILoggerFactory();251 try {252 Method reset = factory.getClass().getDeclaredMethod("reset");253 reset.invoke(factory);254 Class clazz = Class.forName("ch.qos.logback.classic.util.ContextInitializer");255 Object temp = clazz.getDeclaredConstructors()[0].newInstance(factory);256 Method autoConfig = clazz.getDeclaredMethod("autoConfig");257 autoConfig.invoke(temp);258 } catch (Exception e) {259 // ignore260 }261 }262 @Override263 public Void call() throws Exception {264 if (clean) {265 FileUtils.deleteDirectory(new File(output));266 logger.info("deleted directory: {}", output);267 }268 if (jobServerUrl != null) {269 JobExecutor.run(jobServerUrl);270 return null;271 }272 if (debugPort != -1) {273 DapServer server = new DapServer(debugPort);274 server.waitSync();275 return null;276 }277 if (paths != null) {278 Results results = Runner279 .path(paths).tags(tags).scenarioName(name)280 .karateEnv(env)281 .workingDir(workingDir)282 .buildDir(output)283 .configDir(configDir)284 .outputHtmlReport(isOutputHtmlReport())285 .outputCucumberJson(isOutputCucumberJson())286 .outputJunitXml(isOutputJunitXml())287 .dryRun(dryRun)288 .hooks(createHooks())289 .parallel(threads);290 if (results.getFailCount() > 0) {291 Exception ke = new KarateException("there are test failures !");292 StackTraceElement[] newTrace = new StackTraceElement[]{293 new StackTraceElement(".", ".", ".", -1)294 };295 ke.setStackTrace(newTrace);296 throw ke;297 }298 return null;299 }300 if (importFile != null) {301 new PostmanConverter().convert(importFile, output);302 return null;303 }304 if (clean) {305 return null;306 }307 if (serve) {308 ServerConfig config = new ServerConfig(workingDir.getPath());309 RequestHandler handler = new RequestHandler(config);310 HttpServer server = HttpServer311 .handler(handler)312 .port(port)313 .corsEnabled(true) 314 .build();315 server.waitSync();316 return null;317 }318 if (mock == null) {319 CommandLine.usage(this, System.err);320 return null;321 }322 // these files will not be created, unless ssl or ssl proxying happens323 // and then they will be lazy-initialized...
Source:RequestHandler.java
...34/**35 *36 * @author pthomas337 */38public class RequestHandler implements ServerHandler {39 private static final Logger logger = LoggerFactory.getLogger(RequestHandler.class);40 private final SessionStore sessionStore;41 private final KarateTemplateEngine engine;42 private final String homePagePath;43 private final ServerConfig config;44 private final Function<Request, ServerContext> contextFactory;45 private final ResourceResolver resourceResolver;46 private final String stripHostContextPath;47 public RequestHandler(ServerConfig config) {48 this.config = config;49 contextFactory = config.getContextFactory();50 resourceResolver = config.getResourceResolver();51 engine = TemplateUtils.forServer(config);52 homePagePath = config.getHomePagePath();53 sessionStore = config.getSessionStore();54 stripHostContextPath = config.isStripContextPathFromRequest() ? config.getHostContextPath() : null;55 }56 @Override57 public Response handle(Request request) {58 long startTime = System.currentTimeMillis();59 if (stripHostContextPath != null) {60 String path = request.getPath();61 if (path.startsWith(stripHostContextPath)) {...
RequestHandler
Using AI Code Generation
1import com.intuit.karate.http.RequestHandler;2import com.intuit.karate.http.HttpClient;3import com.intuit.karate.http.HttpConfig;4import com.intuit.karate.http.HttpRequest;5import com.intuit.karate.http.HttpResponse;6import static com.intuit.karate.http.HttpMethod.*;7import com.intuit.karate.http.HttpException;8import com.intuit.karate.http.HttpMethod;9import com.intuit.karate.http.HttpUtils;10import com.intuit.karate.http.MultiValuedMap;11import com.intuit.karate.http.HttpHeaders;12import com.intuit.karate.http.HttpCookie;13import com.intuit.karate.http.HttpStatusCodeException;14import com.intuit.karate.http.HttpStatusCode;15import com.intuit.karate.http.HttpRequestBuilder;16import com.intuit.karate.http.HttpResponseBuilder;17import com.intuit.karate.http.HttpRequestConfig;18import com.intuit.karate.http.HttpResponseConfig;19import com.intuit.karate.http.HttpResponseHandler;20import com.intuit.karate.http.HttpResponseHandlerBuilder;21import com.intuit.karate.http.HttpResponseHandlerConfig;22import com.intuit.karate.http.H
RequestHandler
Using AI Code Generation
1import com.intuit.karate.http.RequestHandler;2import com.intuit.karate.http.HttpRequest;3import com.intuit.karate.http.HttpResponse;4import com.intuit.karate.http.HttpConfig;5import com.intuit.karate.http.HttpUtils;6import com.intuit.karate.http.HttpMethod;7import com.intuit.karate.http.HttpClient;8import com.intuit.karate.http.HttpClientFactory;9import java.util.Map;10import java.util.HashMap;11import java.util.List;12import java.util.ArrayList;13import java.util.Arrays;14import java.util.stream.Collectors;15import java.util.concurrent.TimeUnit;16import java.util.concurrent.locks.Lock;17import java.util.concurrent.locks.ReentrantLock;18import java.util.concurrent.Callable;19import java.util.concurrent.FutureTask;20import java.util.concurrent.ExecutionException;21import java.util.concurrent.ThreadLocalRandom;22import java.util.concurrent.atomic.AtomicBoolean;23import java.util.concurrent.ConcurrentHashMap;24import java.util.concurrent.Semaphore;25import java.util.concurrent.atomic.AtomicInteger;26import java.util.concurrent.locks.ReentrantReadWriteLock;27import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;28import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;29import java.util.concurrent.locks.LockSupport;30import java.util.concurrent.ScheduledThreadPoolExecutor;31import java.util.concurrent.ScheduledFuture;32import java.util.concurrent.TimeUnit;33import java.util.concurrent.locks.Condition;34import java.util.concurrent.locks.ReentrantLock;35import java.util.concurrent.atomic.AtomicInteger;36import java.util.concurrent.atomic.AtomicLong;37import java.util.concurrent.atomic.AtomicReference;38import java.util.concurrent.locks.StampedLock;39import java.util.concurrent.locks.ReentrantLock;40import java.util.concurrent.locks.Condition;41import java.util.concurrent.locks.ReentrantLock;
RequestHandler
Using AI Code Generation
1import com.intuit.karate.http.RequestHandler;2import com.intuit.karate.http.HttpResponse;3import com.intuit.karate.http.HttpMethod;4import com.intuit.karate.http.MultiPartItem;5import java.util.Map;6import java.util.HashMap;7public class RequestHandlerExample {8 public static void main(String[] args) {9 RequestHandler handler = new RequestHandler();10 handler.setMethod(HttpMethod.POST);11 handler.addHeader("Content-Type", "application/json");12 handler.addHeader("Accept", "application/json");13 handler.setBody("{\"name\":\"John\"}");14 HttpResponse response = handler.execute();15 System.out.println("Response: " + response.getBody());16 }17}18import com.intuit.karate.http.RequestHandler;19import com.intuit.karate.http.HttpResponse;20import com.intuit.karate.http.HttpMethod;21import com.intuit.karate.http.MultiPartItem;22import java.util.Map;23import java.util.HashMap;24public class RequestHandlerExample {25 public static void main(String[] args) {26 RequestHandler handler = new RequestHandler();27 handler.setMethod(HttpMethod.POST);28 handler.addHeader("Content-Type", "multipart/form-data");29 handler.addHeader("Accept", "application/json");30 Map<String, Object> params = new HashMap<>();31 params.put("name", "John");32 params.put("age", 30);33 MultiPartItem item = new MultiPartItem("params", params, "application/json");34 handler.addMultiPartItem(item);35 HttpResponse response = handler.execute();36 System.out.println("Response: " + response.getBody());37 }38}39import com.intuit.karate.http.RequestHandler;40import com.intuit.karate.http.HttpResponse;41import com.intuit.karate.http.HttpMethod;42import com.intuit.karate.http.MultiPartItem;43import java.util.Map;44import java.util.HashMap;45public class RequestHandlerExample {46 public static void main(String[] args) {47 RequestHandler handler = new RequestHandler();
RequestHandler
Using AI Code Generation
1package demo;2import com.intuit.karate.http.RequestHandler;3import com.intuit.karate.http.HttpResponse;4import com.intuit.karate.http.HttpMethod;5import java.util.Map;6import java.util.HashMap;7import java.util.List;8import java.util.ArrayList;9import java.util.Collections;10import java.util.LinkedHashMap;11import java.util.Arrays;12import java.util.stream.Collectors;13import java.util.stream.Stream;14import java.util.Iterator;15import java.util.regex.Matcher;16import java.util.regex.Pattern;17import java.util.concurrent.TimeUnit;18import java.util.concurrent.atomic.AtomicInteger;19import java.util.concurrent.atomic.AtomicBoolean;20import java.util.concurrent.atomic.AtomicLong;21import java.util.concurrent.atomic.AtomicReference;22import java.util.concurrent.ConcurrentHashMap;23import java.util.concurrent.ConcurrentMap;24import java.util.concurrent.ConcurrentLinkedQueue;25import java.util.concurrent.ConcurrentSkipListMap;26import java.util.concurrent.Callable;27import java.util.concurrent.ExecutorService;28import java.util.concurrent.Executors;29import java.util.concurrent.Future;30import java.util.concurrent.ScheduledExecutorService;31import java.util.concurrent.ScheduledFuture;32import java.util.concurrent.ScheduledThreadPoolExecutor;33import java.util.concurrent.TimeUnit;34import java.util.concurrent.atomic.AtomicInteger;35import java.util.concurrent.atomic.AtomicBoolean;36import java.util.concurrent.atomic.AtomicLong;37import java.util.concurrent.atomic.AtomicReference;38import java.util.concurrent.ConcurrentHashMap;39import java.util.concurrent.ConcurrentMap;40import java.util.concurrent.ConcurrentLinkedQueue;41import java.util.concurrent.ConcurrentSkipListMap;42import java.util.concurrent.Callable;43import java.util.concurrent.ExecutorService;44import java.util.concurrent.Executors;45import java.util.concurrent.Future;46import java.util.concurrent.ScheduledExecutorService;47import java.util.concurrent.ScheduledFuture;48import java.util.concurrent.ScheduledThreadPoolExecutor;49import java.util.concurrent.TimeUnit;50import java.util.function.Predicate;51import java.util.function.Function;52import java.util.function.Consumer;53import java.util.function.Supplier;54import java.util.function.BiConsumer;55import java.util.function.BiFunction;56import java.util.function.BinaryOperator;57import java.util.function.UnaryOperator;58import java.util.function.ToIntFunction;59import java.util.function.ToDoubleFunction;60import java.util.function.ToLongFunction;61import java.util.function.BiPredicate;62import java.util.function.LongPredicate;63import java.util.function.IntPredicate;64import java.util.function.DoublePredicate;65import java.util.function.BooleanSupplier;66import java.util.function.IntSupplier;67import java.util.function.LongSupplier;68import java.util.function.DoubleSupplier;69import java.util.function.IntFunction;70import java.util.function.Long
RequestHandler
Using AI Code Generation
1import com.intuit.karate.http.RequestHandler;2import com.intuit.karate.http.Response;3 .builder()4 .build()5 .get();6System.out.println(response.getBodyAsString());7 .builder()8 .build()9 .post();10System.out.println(response.getBodyAsString());11 .builder()12 .build()13 .put();14System.out.println(response.getBodyAsString());15 .builder()16 .build()17 .delete();18System.out.println(response.getBodyAsString());19 .builder()20 .build()21 .head();22System.out.println(response.getBodyAsString());23 .builder()24 .build()25 .patch();26System.out.println(response.getBodyAsString());27 .builder()28 .build()29 .options();30System.out.println(response.getBodyAsString());31import com.intuit.karate.http.RequestHandler;32import com.intuit.karate.http.Response;33 .builder()34 .build()35 .get();36System.out.println(response.getBodyAsString());37 .builder()38 .build()39 .post();40System.out.println(response.getBodyAsString());41 .builder()42 .build()43 .put();44System.out.println(response.getBodyAsString());45 .builder()
RequestHandler
Using AI Code Generation
1import com.intuit.karate.http.RequestHandler;2import com.intuit.karate.http.HttpResponse;3import com.intuit.karate.http.HttpMethod;4import java.util.Map;5public class RequestHandlerExample {6 public static void main(String[] args) {7 RequestHandler handler = new RequestHandler();8 HttpResponse response = handler.request(HttpMethod.GET, url, null);9 System.out.println("Status code: " + response.getStatusCode());10 System.out.println("Response body: " + response.getBody());11 System.out.println("Headers: " + response.getHeaders());12 }13}14import com.intuit.karate.http.RequestHandler;15import com.intuit.karate.http.HttpResponse;16import com.intuit.karate.http.HttpMethod;17import java.util.Map;18public class RequestHandlerExample {19 public static void main(String[] args) {20 Map<String, Object> headers = new HashMap<>();21 headers.put("Content-Type", "application/json");22 RequestHandler handler = new RequestHandler();23 HttpResponse response = handler.request(HttpMethod.GET, url, headers);24 System.out.println("Status code: " + response.getStatusCode());25 System.out.println("Response body: " + response.getBody());26 System.out.println("Headers: " + response.getHeaders());27 }28}29import com.intuit.karate.http.RequestHandler;30import com.intuit.karate.http.HttpResponse;31import com.intuit.karate.http.HttpMethod;32import java.util.Map;33public class RequestHandlerExample {34 public static void main(String[] args) {35 Map<String, Object> headers = new HashMap<>();36 headers.put("Content-Type", "application/json");37 RequestHandler handler = new RequestHandler();38 HttpResponse response = handler.request(HttpMethod.GET, url, headers);39 System.out.println("Status code: " + response.getStatusCode());40 System.out.println("Response body: " + response.getBody());41 System.out.println("Headers: " + response.getHeaders());42 }43}
RequestHandler
Using AI Code Generation
1import com.intuit.karate.http.RequestHandler;2import com.intuit.karate.http.HttpResponse;3public class 4 {4 public static void main(String[] args) {5 RequestHandler handler = new RequestHandler();6 System.out.println(response.getBodyAsString());7 }8}9import com.intuit.karate.http.RequestHandler;10import com.intuit.karate.http.HttpResponse;11public class 5 {12 public static void main(String[] args) {13 RequestHandler handler = new RequestHandler();14 System.out.println(response.getBodyAsString());15 }16}17import com.intuit.karate.http.RequestHandler;18import com.intuit.karate.http.HttpResponse;19public class 6 {20 public static void main(String[] args) {21 RequestHandler handler = new RequestHandler();22 System.out.println(response.getBodyAsString());23 }24}25import com.intuit.karate.http.RequestHandler;26import com.intuit.karate.http.HttpResponse;27public class 7 {28 public static void main(String[] args) {29 RequestHandler handler = new RequestHandler();30 System.out.println(response.getBodyAsString());31 }32}
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!!