Best Citrus code snippet using com.consol.citrus.kubernetes.model.KubernetesRequest
Source:KubernetesMessageConverter.java
...17import com.consol.citrus.context.TestContext;18import com.consol.citrus.exceptions.CitrusRuntimeException;19import com.consol.citrus.kubernetes.command.*;20import com.consol.citrus.kubernetes.endpoint.KubernetesEndpointConfiguration;21import com.consol.citrus.kubernetes.model.KubernetesRequest;22import com.consol.citrus.kubernetes.model.KubernetesResponse;23import com.consol.citrus.message.Message;24import com.consol.citrus.message.MessageConverter;25import org.springframework.util.StringUtils;26import java.io.IOException;27import java.util.HashMap;28import java.util.Map;29/**30 * @author Christoph Deppisch31 * @since 2.732 */33public class KubernetesMessageConverter implements MessageConverter<KubernetesCommand<?>, KubernetesCommand<?>, KubernetesEndpointConfiguration> {34 @Override35 public KubernetesCommand<?> convertOutbound(Message message, KubernetesEndpointConfiguration endpointConfiguration, TestContext context) {36 KubernetesCommand<?> command = getCommand(message, endpointConfiguration);37 convertOutbound(command, message, endpointConfiguration, context);38 return command;39 }40 @Override41 public void convertOutbound(KubernetesCommand<?> command, Message message, KubernetesEndpointConfiguration endpointConfiguration, TestContext context) {42 }43 @Override44 public Message convertInbound(KubernetesCommand<?> command, KubernetesEndpointConfiguration endpointConfiguration, TestContext context) {45 KubernetesResponse response = new KubernetesResponse();46 KubernetesMessage message = KubernetesMessage.response(response);47 response.setCommand(command.getName());48 message.setHeader(KubernetesMessageHeaders.COMMAND, response.getCommand());49 for (Map.Entry<String, Object> header : createMessageHeaders(command).entrySet()) {50 message.setHeader(header.getKey(), header.getValue());51 }52 CommandResult<?> commandResult = command.getCommandResult();53 if (commandResult != null) {54 if (commandResult.getResult() != null) {55 response.setResult(commandResult.getResult());56 }57 if (commandResult.hasError()) {58 response.setError(commandResult.getError().getMessage());59 }60 if (commandResult instanceof WatchEventResult) {61 response.setAction(((WatchEventResult) commandResult).getAction().name());62 message.setHeader(KubernetesMessageHeaders.ACTION, ((WatchEventResult) commandResult).getAction().name());63 }64 }65 return message;66 }67 /**68 * Creates a new kubernetes command message model object from message headers.69 * @param commandName70 * @return71 */72 private KubernetesCommand<?> getCommandByName(String commandName) {73 if (!StringUtils.hasText(commandName)) {74 throw new CitrusRuntimeException("Missing command name property");75 }76 switch (commandName) {77 case "info":78 return new Info();79 case "list-events":80 return new ListEvents();81 case "list-endpoints":82 return new ListEndpoints();83 case "create-pod":84 return new CreatePod();85 case "get-pod":86 return new GetPod();87 case "delete-pod":88 return new DeletePod();89 case "list-pods":90 return new ListPods();91 case "watch-pods":92 return new WatchPods();93 case "list-namespaces":94 return new ListNamespaces();95 case "watch-namespaces":96 return new WatchNamespaces();97 case "list-nodes":98 return new ListNodes();99 case "watch-nodes":100 return new WatchNodes();101 case "list-replication-controllers":102 return new ListReplicationControllers();103 case "watch-replication-controllers":104 return new WatchReplicationControllers();105 case "create-service":106 return new CreateService();107 case "get-service":108 return new GetService();109 case "delete-service":110 return new DeleteService();111 case "list-services":112 return new ListServices();113 case "watch-services":114 return new WatchServices();115 default:116 throw new CitrusRuntimeException("Unknown kubernetes command: " + commandName);117 }118 }119 /**120 * Reads basic command information and converts to message headers.121 * @param command122 * @return123 */124 private Map<String,Object> createMessageHeaders(KubernetesCommand<?> command) {125 Map<String, Object> headers = new HashMap<String, Object>();126 headers.put(KubernetesMessageHeaders.COMMAND, command.getName());127 for (Map.Entry<String, Object> entry : command.getParameters().entrySet()) {128 headers.put(entry.getKey(), entry.getValue());129 }130 return headers;131 }132 /**133 * Reads Citrus internal mail message model object from message payload. Either payload is actually a mail message object or134 * XML payload String is unmarshalled to mail message object.135 *136 * @param message137 * @param endpointConfiguration138 * @return139 */140 private KubernetesCommand<?> getCommand(Message message, KubernetesEndpointConfiguration endpointConfiguration) {141 Object payload = message.getPayload();142 KubernetesCommand<?> command;143 if (message instanceof KubernetesMessage) {144 command = createCommandFromRequest(message.getPayload(KubernetesRequest.class));145 } else if (message.getHeaders().containsKey(KubernetesMessageHeaders.COMMAND) &&146 (payload == null || !StringUtils.hasText(payload.toString()))) {147 command = getCommandByName(message.getHeader(KubernetesMessageHeaders.COMMAND).toString());148 } else if (payload instanceof KubernetesCommand) {149 command = (KubernetesCommand) payload;150 } else {151 try {152 KubernetesRequest request = endpointConfiguration.getObjectMapper()153 .readValue(message.getPayload(String.class), KubernetesRequest.class);154 command = createCommandFromRequest(request);155 } catch (IOException e) {156 throw new CitrusRuntimeException("Failed to read kubernetes request from payload", e);157 }158 }159 if (command == null) {160 throw new CitrusRuntimeException("Unable to create proper Kubernetes command from payload: " + payload);161 }162 return command;163 }164 private KubernetesCommand<?> createCommandFromRequest(KubernetesRequest request) {165 KubernetesCommand<?> command = getCommandByName(request.getCommand());166 if (StringUtils.hasText(request.getName())) {167 command.getParameters().put(KubernetesMessageHeaders.NAME, request.getName());168 }169 if (StringUtils.hasText(request.getNamespace())) {170 command.getParameters().put(KubernetesMessageHeaders.NAMESPACE, request.getNamespace());171 }172 if (StringUtils.hasText(request.getLabel())) {173 command.getParameters().put(KubernetesMessageHeaders.LABEL, request.getLabel());174 }175 return command;176 }177}...
Source:KubernetesMessage.java
...15 */16package com.consol.citrus.kubernetes.message;17import com.consol.citrus.exceptions.CitrusRuntimeException;18import com.consol.citrus.kubernetes.command.*;19import com.consol.citrus.kubernetes.model.KubernetesRequest;20import com.consol.citrus.kubernetes.model.KubernetesResponse;21import com.consol.citrus.message.DefaultMessage;22import com.fasterxml.jackson.databind.ObjectMapper;23import io.fabric8.kubernetes.api.model.KubernetesResource;24import io.fabric8.kubernetes.client.KubernetesClientException;25import io.fabric8.kubernetes.client.Watcher;26import java.io.IOException;27import java.util.Map;28/**29 * @author Christoph Deppisch30 * @since 2.731 */32public class KubernetesMessage extends DefaultMessage {33 private ObjectMapper mapper = new ObjectMapper();34 private KubernetesRequest request;35 private KubernetesResponse response;36 /**37 * Prevent traditional instantiation.38 */39 private KubernetesMessage() { super(); }40 /**41 * Constructor using payload and headers.42 * @param payload43 * @param headers44 */45 private KubernetesMessage(Object payload, Map<String, Object> headers) {46 super(payload, headers);47 }48 /**49 * Constructor using response.50 * @param request51 */52 private KubernetesMessage(KubernetesRequest request) {53 this.request = request;54 }55 /**56 * Constructor using response.57 * @param response58 */59 private KubernetesMessage(KubernetesResponse response) {60 this.response = response;61 }62 /**63 * Response generating instantiation.64 * @param response65 * @return66 */67 public static KubernetesMessage response(KubernetesResponse response) {68 return new KubernetesMessage(response);69 }70 /**71 * Response generating instantiation.72 * @param command73 * @param result74 * @return75 */76 public static KubernetesMessage response(String command, KubernetesResource<?> result) {77 KubernetesResponse response = new KubernetesResponse();78 response.setCommand(command);79 response.setResult(result);80 return new KubernetesMessage(response);81 }82 /**83 * Response generating instantiation.84 * @param command85 * @param action86 * @param result87 * @return88 */89 public static KubernetesMessage response(String command, Watcher.Action action, KubernetesResource<?> result) {90 KubernetesResponse response = new KubernetesResponse();91 response.setCommand(command);92 response.setResult(result);93 response.setAction(action.name());94 return new KubernetesMessage(response);95 }96 /**97 * Error generating instantiation.98 * @param error99 * @return100 */101 public static KubernetesMessage response(String command, KubernetesClientException error) {102 return response(command, error.getMessage());103 }104 /**105 * Error generating instantiation.106 * @param error107 * @return108 */109 public static KubernetesMessage response(String command, String error) {110 KubernetesResponse response = new KubernetesResponse();111 response.setCommand(command);112 response.setError(error);113 return new KubernetesMessage(response);114 }115 /**116 * Request generating instantiation.117 * @param request118 * @return119 */120 public static KubernetesMessage request(KubernetesRequest request) {121 return new KubernetesMessage(request);122 }123 /**124 * Request generating instantiation.125 * @param command126 * @return127 */128 public static KubernetesMessage request(KubernetesCommand<?> command) {129 KubernetesRequest request = new KubernetesRequest();130 request.setCommand(command.getName());131 for (Map.Entry<String, Object> entry : command.getParameters().entrySet()) {132 if (entry.getKey().equals(KubernetesMessageHeaders.NAME)) {133 request.setName(entry.getValue().toString());134 }135 if (entry.getKey().equals(KubernetesMessageHeaders.NAMESPACE)) {136 request.setNamespace(entry.getValue().toString());137 }138 if (entry.getKey().equals(KubernetesMessageHeaders.LABEL)) {139 request.setLabel(entry.getValue().toString());140 }141 }142 return new KubernetesMessage(request);143 }144 @Override145 public <T> T getPayload(Class<T> type) {146 try {147 if (KubernetesRequest.class.isAssignableFrom(type)) {148 if (getPayload() instanceof KubernetesRequest) {149 return (T) getPayload();150 }151 return (T) mapper.readValue(getPayload(String.class), KubernetesRequest.class);152 } else if (KubernetesResponse.class.isAssignableFrom(type)) {153 if (getPayload() instanceof KubernetesResponse) {154 return (T) getPayload();155 }156 return (T) mapper.readValue(getPayload(String.class), KubernetesRequest.class);157 } else if (String.class.equals(type)) {158 if (request != null) {159 return (T) mapper.writeValueAsString(request);160 } else if (response != null) {161 return (T) mapper.writeValueAsString(response);162 }163 }164 } catch (IOException e) {165 throw new CitrusRuntimeException("Failed to convert payload to required type: " + type, e);166 }167 return super.getPayload(type);168 }169}...
KubernetesRequest
Using AI Code Generation
1import com.consol.citrus.annotations.CitrusTest;2import com.consol.citrus.dsl.design.TestDesigner;3import com.consol.citrus.dsl.junit.JUnit4CitrusTestDesigner;4import com.consol.citrus.kubernetes.actions.KubernetesExecuteAction;5import com.consol.citrus.kubernetes.message.KubernetesMessageHeaders;6import com.consol.citrus.kubernetes.model.KubernetesRequest;7import com.consol.citrus.kubernetes.model.KubernetesResponse;8import com.consol.citrus.kubernetes.model.KubernetesVerb;9import com.consol.citrus.message.MessageType;10import com.consol.citrus.testng.CitrusParameters;11import org.springframework.http.HttpStatus;12import org.springframework.http.MediaType;13import org.testng.annotations.DataProvider;14import org.testng.annotations.Test;15public class KubernetesIT extends JUnit4CitrusTestDesigner {16 @DataProvider(name = "kubernetesProvider")17 public Object[][] kubernetesProvider() {18 return new Object[][] {19 new Object[] { "1" },20 new Object[] { "2" },21 new Object[] { "3" }22 };23 }24 @Test(dataProvider = "kubernetesProvider")25 @CitrusParameters("testId")26 public void kubernetesTest(String testId) {27 variable("testId", testId);28 echo("Kubernetes test with testId = ${testId}");29 description("Kubernetes test with testId = ${testId}");30 parallel(builder -> {31 .actions(32 new KubernetesExecuteAction()33 .client("kubernetesClient")34 .request(KubernetesRequest.builder()35 .apiVersion("v1")36 .kind("Pod")37 .verb(KubernetesVerb.GET)38 .path("/api/v1/namespaces/default/pods")39 .build())40 .extractFromHeader(KubernetesMessageHeaders.KUBERNETES_RESOURCE_VERSION, "resourceVersion")41 );42 .actions(43 new KubernetesExecuteAction()44 .client("kubernetesClient")45 .request(KubernetesRequest.builder()46 .apiVersion("v1")47 .kind("Pod")48 .verb(KubernetesVerb.GET)49 .path("/api/v1/namespaces/default/pods")50 .header("X-Resource-Version", "${resourceVersion}")51 .build())52 .extractFromHeader(KubernetesMessageHeaders.KUBERNET
KubernetesRequest
Using AI Code Generation
1import com.consol.citrus.annotations.CitrusTest;2import com.consol.citrus.dsl.testng.TestNGCitrusTestDesigner;3import com.consol.citrus.kubernetes.actions.KubernetesExecuteAction;4import com.consol.citrus.kubernetes.model.KubernetesRequest;5import org.springframework.http.HttpMethod;6import org.springframework.http.HttpStatus;7import org.testng.annotations.Test;8public class KubernetesExecuteActionJavaIT extends TestNGCitrusTestDesigner {9 public void kubernetesExecuteActionJavaIT() {10 variable("namespace", "default");11 variable("podName", "citrus-pod");12 variable("containerName", "citrus-container");13 KubernetesRequest request = new KubernetesRequest();14 request.setMethod(HttpMethod.POST);15 request.setPath("/api/v1/namespaces/${namespace}/pods");16 request.setBody("classpath:templates/pod.json");17 send(new KubernetesExecuteAction.Builder()18 .request(request)19 .build());20 request = new KubernetesRequest();21 request.setMethod(HttpMethod.GET);22 request.setPath("/api/v1/namespaces/${namespace}/pods/${podName}");23 send(new KubernetesExecuteAction.Builder()24 .request(request)25 .build());26 request = new KubernetesRequest();27 request.setMethod(HttpMethod.GET);28 request.setPath("/api/v1/namespaces/${namespace}/pods/${podName}/log?container=${containerName}");29 send(new KubernetesExecuteAction.Builder()30 .request(request)31 .build());32 request = new KubernetesRequest();33 request.setMethod(HttpMethod.GET);34 request.setPath("/api/v1/namespaces/${namespace}/pods/${podName}/status");35 send(new KubernetesExecuteAction.Builder()36 .request(request)37 .build());38 request = new KubernetesRequest();39 request.setMethod(HttpMethod.DELETE);40 request.setPath("/api/v1/namespaces/${namespace}/pods/${podName}");41 send(new KubernetesExecuteAction.Builder()42 .request(request)43 .build());44 }45}46import com.consol.citrus.annotations.CitrusTest;47import com.consol.c
KubernetesRequest
Using AI Code Generation
1package com.consol.citrus.kubernetes;2import com.consol.citrus.kubernetes.model.KubernetesRequest;3import com.consol.citrus.testng.CitrusParameters;4import org.springframework.beans.factory.annotation.Autowired;5import org.springframework.http.HttpStatus;6import org.springframework.http.MediaType;7import org.testng.annotations.Test;8import static com.consol.citrus.actions.CreateVariablesAction.Builder.createVariable;9import static com.consol.citrus.actions.EchoAction.Builder.echo;10import static com.consol.citrus.actions.ExecutePLSQLAction.Builder.executePLSQL;11import static com.consol.citrus.actions.ExecuteSQLAction.Builder.executeSQL;12import static com.consol.citrus.actions.SendMessageAction.Builder.sendMessage;13import static com.consol.citrus.actions.SleepAction.Builder.sleep;14import static com.consol.citrus.actions.StopTimeAction.Builder.stopTime;15import static com.consol.citrus.actions.StoreTimeAction.Builder.storeTime;16import static com.consol.citrus.actions.TraceVariablesAction.Builder.traceVariables;17import static com.consol.citrus.actions.UpdateVariablesAction.Builder.updateVariable;18import static com.consol.citrus.actions.WaitAction.Builder.waitFor;19import static com.consol.citrus.container.Assert.Builder.assertException;20import static com.consol.citrus.container.FinallySequence.Builder.doFinally;21import static com.consol.citrus.container.Iterate.Builder.iterate;22import static com.consol.citrus.container.Parallel.Builder.parallel;23import static com.consol.citrus.container.RepeatOnErrorUntilTrue.Builder.repeatOnErrorUntilTrue;24import static com.consol.citrus.container.Sequence.Builder.sequential;25import static com.c
KubernetesRequest
Using AI Code Generation
1KubernetesRequest request = new KubernetesRequest();2request.setMethod("POST");3request.setPath("/api/v1/namespaces/{namespace}/pods");4request.setBody("{" +5" \"metadata\": {" +6" }," +7" \"spec\": {" +8" {" +9" }" +10" }" +11"}");12request.setHeaders(Collections.singletonMap("Content-Type", "application/json"));13new KubernetesActionBuilder()14 .client("kubernetesClient")15 .request(request)16 .build();17new KubernetesActionBuilder()18 .client("kubernetesClient")19 .request()20 .method("POST")21 .path("/api/v1/namespaces/{namespace}/pods")22 .body("{" +23" \"metadata\": {" +24" }," +25" \"spec\": {" +26" {" +27" }" +28" }" +29"}")30 .header("Content-Type", "application/json")31 .build();32new KubernetesActionBuilder()33 .client("kubernetesClient")34 .request()35 .method("POST")36 .path("/api/v1/namespaces/{namespace}/pods")37 .body(new FileResource(new File("src/test/resources/templates/pod.json")))38 .header("Content-Type", "application/json")39 .build();
KubernetesRequest
Using AI Code Generation
1KubernetesRequest request = new KubernetesRequest();2request.setMethod("GET");3request.setPath("/api/v1/namespaces");4request.setBody("{5{6\"metadata\": {7\"labels\": {8}9}10}11}");12request.setHeaders(Collections.singletonMap("Content-Type", "application/json"));13request.setQueryParams(Collections.singletonMap("labelSelector", "name=default"));14KubernetesResponse response = new KubernetesResponse();15response.setStatusCode(HttpStatus.OK.value());16response.setBody("{17{18\"metadata\": {19\"labels\": {20}21}22}23}");24KubernetesActionBuilder builder = new KubernetesActionBuilder();25builder.apply(request, response);26builder.build().execute(context);27KubernetesAction action = new KubernetesAction();28action.setRequest(request);29action.setResponse(response);30action.execute(context);
KubernetesRequest
Using AI Code Generation
1KubernetesRequest request = new KubernetesRequest();2request.setMethod("GET");3request.setPath("/api/v1/namespaces/default/pods");4request.setHeaders(Collections.singletonMap("Authorization", "Bearer " + token));5KubernetesResponse response = new KubernetesResponse();6response.setBody("kubernetes-pod-response.xml");7response.setHeaders(Collections.singletonMap("Content-Type", "application/json"));8response.setStatus(200);9KubernetesActionBuilder kubernetesActionBuilder = new KubernetesActionBuilder();10kubernetesActionBuilder.client("kubernetesClient")11.endpoint(kubernetesEndpoint)12.request(request)13.response(response)14.build();15public class KubernetesTest extends TestCase {16 public void testKubernetes() {17 kubernetesActionBuilder.execute(context);18 }19}20public class KubernetesTest extends TestCase {21 public void testKubernetes() {22 kubernetesActionBuilder.execute(context);23 }24}25public class KubernetesTest extends TestCase {26 public void testKubernetes() {27 kubernetesActionBuilder.execute(context);28 }29}30public class KubernetesTest extends TestCase {31 public void testKubernetes() {32 kubernetesActionBuilder.execute(context);33 }
KubernetesRequest
Using AI Code Generation
1public class 3 extends AbstractTestContainer {2 private TestRunner runner;3 public void 3() {4 runner.kubernetes()5 .request(KubernetesRequest6 .builder()7 .method(KubernetesMethod.GET)8 .path("/api/v1/namespaces/default/pods")9 .build())10 .validate()11 .statusCode(HttpStatus.OK);12 }13}14public class 4 extends AbstractTestContainer {15 private TestRunner runner;16 public void 4() {17 runner.kubernetes()18 .request(KubernetesRequestBuilder19 .get()20 .path("/api/v1/namespaces/default/pods")21 .build())22 .validate()23 .statusCode(HttpStatus.OK);24 }25}26public class 5 extends AbstractTestContainer {27 private TestRunner runner;28 public void 5() {29 runner.kubernetes()30 .request(KubernetesRequestBuilder31 .get()32 .path("/api/v1/namespaces/default/pods")33 .build())34 .validate()35 .body("items[0].metadata.name", "citrus:startsWith('citrus-')");36 }37}38public class 6 extends AbstractTestContainer {39 private TestRunner runner;40 public void 6() {41 runner.kubernetes()42 .request(KubernetesRequestBuilder43 .get()44 .path("/api/v1/namespaces/default/pods")45 .build())46 .validate()47 .body("items[0].metadata.name", "citrus:startsWith('citrus-')")48 .body("items[0].metadata.name", "citrus:endsWith('-pod')");49 }50}51public class 7 extends AbstractTestContainer {
KubernetesRequest
Using AI Code Generation
1public class 3 extends TestNGCitrusTestDesigner {2 public void 3() {3 variable("namespace", "default");4 variable("podName", "citrus-3");5 variable("podImage", "nginx:1.15.2");6 variable("podPort", "80");7 variable("podPortName", "http");8 variable("podPortProtocol", "TCP");9 variable("podPortContainerPort", "80");10 variable("podPortHostPort", "80");11 variable("podPortHostIP", "
KubernetesRequest
Using AI Code Generation
1import com.consol.citrus.annotations.CitrusTest;2import com.consol.citrus.dsl.testng.TestNGCitrusTestRunner;3import com.consol.citrus.kubernetes.actions.KubernetesExecuteAction;4import com.consol.citrus.kubernetes.actions.KubernetesExecuteActionBuilder;5import com.consol.citrus.kubernetes.actions.KubernetesQueryAction;6import com.consol.citrus.kubernetes.actions.KubernetesQueryActionBuilder;7import com.consol.citrus.kubernetes.client.KubernetesClient;8import com.consol.citrus.kubernetes.message.KubernetesMessageHeaders;9import com.consol.citrus.kubernetes.model.v1.KubernetesService;10import com.consol.citrus.kubernetes.model.v1.KubernetesServiceList;11import com.consol.citrus.kubernetes.model.v1.KubernetesServiceSpec;12import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatus;13import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancer;14import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerIngress;15import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerIngressBuilder;16import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerIngresses;17import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerIngressesBuilder;18import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerIngressesList;19import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerIngressesListBuilder;20import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerPorts;21import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerPortsBuilder;22import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerPortsList;23import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerPortsListBuilder;24import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerPortsListList;25import com.consol.citrus.kubernetes.model.v1.KubernetesServiceStatusLoadBalancerPortsListListBuilder;26import com.consol.citrus.kubernetes
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!!