Best Selenium code snippet using org.openqa.selenium.grid.data.SessionRequestCapability.getDesiredCapabilities
Source:LocalDistributor.java  
...315    Map<String, EventAttributeValue> attributeMap = new HashMap<>();316    try {317      attributeMap.put(AttributeKey.LOGGER_CLASS.getKey(),318        EventAttribute.setValue(getClass().getName()));319      attributeMap.put("request.payload", EventAttribute.setValue(request.getDesiredCapabilities().toString()));320      String sessionReceivedMessage = "Session request received by the distributor";321      span.addEvent(sessionReceivedMessage, attributeMap);322      LOG.info(String.format("%s: \n %s", sessionReceivedMessage, request.getDesiredCapabilities()));323      // If there are no capabilities at all, something is horribly wrong324      if (request.getDesiredCapabilities().isEmpty()) {325        SessionNotCreatedException exception =326          new SessionNotCreatedException("No capabilities found in session request payload");327        EXCEPTION.accept(attributeMap, exception);328        attributeMap.put(AttributeKey.EXCEPTION_MESSAGE.getKey(),329          EventAttribute.setValue("Unable to create session. No capabilities found: " +330            exception.getMessage()));331        span.addEvent(AttributeKey.EXCEPTION_EVENT.getKey(), attributeMap);332        return Either.left(exception);333      }334      boolean retry = false;335      SessionNotCreatedException lastFailure = new SessionNotCreatedException("Unable to create new session");336      for (Capabilities caps : request.getDesiredCapabilities()) {337        if (!isSupported(caps)) {338          continue;339        }340        // Try and find a slot that we can use for this session. While we341        // are finding the slot, no other session can possibly be started.342        // Therefore, spend as little time as possible holding the write343        // lock, and release it as quickly as possible. Under no344        // circumstances should we try to actually start the session itself345        // in this next block of code.346        SlotId selectedSlot = reserveSlot(request.getRequestId(), caps);347        if (selectedSlot == null) {348          LOG.info(String.format("Unable to find slot for request %s. May retry: %s ", request.getRequestId(), caps));349          retry = true;350          continue;351        }352        CreateSessionRequest singleRequest = new CreateSessionRequest(353          request.getDownstreamDialects(),354          caps,355          request.getMetadata());356        try {357          CreateSessionResponse response = startSession(selectedSlot, singleRequest);358          sessions.add(response.getSession());359          model.setSession(selectedSlot, response.getSession());360          SessionId sessionId = response.getSession().getId();361          Capabilities sessionCaps = response.getSession().getCapabilities();362          String sessionUri = response.getSession().getUri().toString();363          SESSION_ID.accept(span, sessionId);364          CAPABILITIES.accept(span, sessionCaps);365          SESSION_ID_EVENT.accept(attributeMap, sessionId);366          CAPABILITIES_EVENT.accept(attributeMap, sessionCaps);367          span.setAttribute(SESSION_URI.getKey(), sessionUri);368          attributeMap.put(SESSION_URI.getKey(), EventAttribute.setValue(sessionUri));369          String sessionCreatedMessage = "Session created by the distributor";370          span.addEvent(sessionCreatedMessage, attributeMap);371          LOG.info(String.format("%s. Id: %s, Caps: %s", sessionCreatedMessage, sessionId, sessionCaps));372          return Either.right(response);373        } catch (SessionNotCreatedException e) {374          model.setSession(selectedSlot, null);375          lastFailure = e;376        }377      }378      // If we've made it this far, we've not been able to start a session379      if (retry) {380        lastFailure = new RetrySessionRequestException(381          "Will re-attempt to find a node which can run this session",382          lastFailure);383        attributeMap.put(384          AttributeKey.EXCEPTION_MESSAGE.getKey(),385          EventAttribute.setValue("Will retry session " + request.getRequestId()));386      } else {387        EXCEPTION.accept(attributeMap, lastFailure);388        attributeMap.put(AttributeKey.EXCEPTION_MESSAGE.getKey(),389          EventAttribute.setValue("Unable to create session: " + lastFailure.getMessage()));390        span.addEvent(AttributeKey.EXCEPTION_EVENT.getKey(), attributeMap);391      }392      return Either.left(lastFailure);393    } catch (SessionNotCreatedException e) {394      span.setAttribute(AttributeKey.ERROR.getKey(), true);395      span.setStatus(Status.ABORTED);396      EXCEPTION.accept(attributeMap, e);397      attributeMap.put(AttributeKey.EXCEPTION_MESSAGE.getKey(),398        EventAttribute.setValue("Unable to create session: " + e.getMessage()));399      span.addEvent(AttributeKey.EXCEPTION_EVENT.getKey(), attributeMap);400      return Either.left(e);401    } catch (UncheckedIOException e) {402      span.setAttribute(AttributeKey.ERROR.getKey(), true);403      span.setStatus(Status.UNKNOWN);404      EXCEPTION.accept(attributeMap, e);405      attributeMap.put(AttributeKey.EXCEPTION_MESSAGE.getKey(),406        EventAttribute.setValue("Unknown error in LocalDistributor while creating session: " + e.getMessage()));407      span.addEvent(AttributeKey.EXCEPTION_EVENT.getKey(), attributeMap);408      return Either.left(new SessionNotCreatedException(e.getMessage(), e));409    } finally {410      span.close();411    }412  }413  private CreateSessionResponse startSession(SlotId selectedSlot, CreateSessionRequest singleRequest) {414    Node node = nodes.get(selectedSlot.getOwningNodeId());415    if (node == null) {416      throw new SessionNotCreatedException("Unable to find owning node for slot");417    }418    Either<WebDriverException, CreateSessionResponse> result;419    try {420      result = node.newSession(singleRequest);421    } catch (SessionNotCreatedException e) {422      result = Either.left(e);423    } catch (RuntimeException e) {424      result = Either.left(new SessionNotCreatedException(e.getMessage(), e));425    }426    if (result.isLeft()) {427      WebDriverException exception = result.left();428      if (exception instanceof SessionNotCreatedException) {429        throw exception;430      }431      throw new SessionNotCreatedException(exception.getMessage(), exception);432    }433    return result.right();434  }435  private SlotId reserveSlot(RequestId requestId, Capabilities caps) {436    Lock writeLock = lock.writeLock();437    writeLock.lock();438    try {439      Set<SlotId> slotIds = slotSelector.selectSlot(caps, getAvailableNodes());440      if (slotIds.isEmpty()) {441        LOG.log(442          getDebugLogLevel(),443          String.format("No slots found for request %s and capabilities %s", requestId, caps));444        return null;445      }446      for (SlotId slotId : slotIds) {447        if (reserve(slotId)) {448          return slotId;449        }450      }451      return null;452    } finally {453      writeLock.unlock();454    }455  }456  private boolean isSupported(Capabilities caps) {457    return getAvailableNodes().stream().anyMatch(node -> node.hasCapability(caps));458  }459  private boolean reserve(SlotId id) {460    Require.nonNull("Slot ID", id);461    Lock writeLock = this.lock.writeLock();462    writeLock.lock();463    try {464      Node node = nodes.get(id.getOwningNodeId());465      if (node == null) {466        LOG.log(getDebugLogLevel(), String.format("Unable to find node with id %s", id));467        return false;468      }469      return model.reserve(id);470    } finally {471      writeLock.unlock();472    }473  }474  public void callExecutorShutdown() {475    LOG.info("Shutting down Distributor executor service");476    regularly.shutdown();477  }478  public class NewSessionRunnable implements Runnable {479    @Override480    public void run() {481      List<SessionRequestCapability> queueContents = sessionQueue.getQueueContents();482      if (rejectUnsupportedCaps) {483        checkMatchingSlot(queueContents);484      }485      int initialSize = queueContents.size();486      boolean retry = initialSize != 0;487      while (retry) {488        // We deliberately run this outside of a lock: if we're unsuccessful489        // starting the session, we just put the request back on the queue.490        // This does mean, however, that under high contention, we might end491        // up starving a session request.492        Set<Capabilities> stereotypes =493            getAvailableNodes().stream()494                .filter(NodeStatus::hasCapacity)495                .map(496                    node ->497                        node.getSlots().stream()498                            .map(Slot::getStereotype)499                            .collect(Collectors.toSet()))500                .flatMap(Collection::stream)501                .collect(Collectors.toSet());502        Optional<SessionRequest> maybeRequest = sessionQueue.getNextAvailable(stereotypes);503        maybeRequest.ifPresent(this::handleNewSessionRequest);504        int currentSize = sessionQueue.getQueueContents().size();505        retry = currentSize != 0 && currentSize != initialSize;506        initialSize = currentSize;507      }508    }509    private void checkMatchingSlot(List<SessionRequestCapability> sessionRequests) {510      for(SessionRequestCapability request : sessionRequests) {511        long unmatchableCount = request.getDesiredCapabilities().stream()512          .filter(caps -> !isSupported(caps))513          .count();514        if (unmatchableCount == request.getDesiredCapabilities().size()) {515          SessionNotCreatedException exception = new SessionNotCreatedException(516            "No nodes support the capabilities in the request");517          sessionQueue.complete(request.getRequestId(), Either.left(exception));518        }519      }520    }521    private void handleNewSessionRequest(SessionRequest sessionRequest) {522      RequestId reqId = sessionRequest.getRequestId();523      try (Span span = TraceSessionRequest.extract(tracer, sessionRequest).createSpan("distributor.poll_queue")) {524        Map<String, EventAttributeValue> attributeMap = new HashMap<>();525        attributeMap.put(526          AttributeKey.LOGGER_CLASS.getKey(),527          EventAttribute.setValue(getClass().getName()));528        span.setAttribute(AttributeKey.REQUEST_ID.getKey(), reqId.toString());...Source:LocalNewSessionQueueTest.java  
...207  public void shouldBeAbleToGetQueueContents() {208    localQueue.injectIntoQueue(sessionRequest);209    List<Set<Capabilities>> response = queue.getQueueContents()210      .stream()211      .map(SessionRequestCapability::getDesiredCapabilities)212      .collect(Collectors.toList());213    assertThat(response).hasSize(1);214    assertEquals(Set.of(CAPS), response.get(0));215  }216  @Test217  public void shouldBeClearQueueAndFireRejectedEvent() throws InterruptedException {218    AtomicBoolean result = new AtomicBoolean(false);219    RequestId requestId = sessionRequest.getRequestId();220    CountDownLatch latch = new CountDownLatch(1);221    bus.addListener(222        NewSessionRejectedEvent.listener(223            response -> {224              result.set(response.getRequestId().equals(requestId));225              latch.countDown();...Source:LocalNewSessionQueue.java  
...268    writeLock.lock();269    try {270      Optional<SessionRequest> maybeRequest =271          queue.stream()272              .filter(req -> req.getDesiredCapabilities().stream().anyMatch(matchesStereotype))273              .findFirst();274      maybeRequest.ifPresent(req -> {275        this.remove(req.getRequestId());276      });277      return maybeRequest;278    } finally {279      writeLock.unlock();280    }281  }282  @Override283  public void complete(RequestId reqId, Either<SessionNotCreatedException, CreateSessionResponse> result) {284    Require.nonNull("New session request", reqId);285    Require.nonNull("Result", result);286    TraceContext context = contexts.getOrDefault(reqId, tracer.getCurrentContext());287    try (Span span = context.createSpan("sessionqueue.completed")) {288      Lock readLock = lock.readLock();289      readLock.lock();290      Data data;291      try {292        data = requests.get(reqId);293      } finally {294        readLock.unlock();295      }296      if (data == null) {297        return;298      }299      Lock writeLock = lock.writeLock();300      writeLock.lock();301      try {302        requests.remove(reqId);303        queue.removeIf(req -> reqId.equals(req.getRequestId()));304        contexts.remove(reqId);305      } finally {306        writeLock.unlock();307      }308      if (result.isLeft()) {309        bus.fire(new NewSessionRejectedEvent(new NewSessionErrorResponse(reqId, result.left().getMessage())));310      }311      data.setResult(result);312    }313  }314  @Override315  public int clearQueue() {316    Lock writeLock = lock.writeLock();317    writeLock.lock();318    try {319      int size = queue.size();320      queue.clear();321      requests.forEach((reqId, data) -> {322        data.setResult(Either.left(new SessionNotCreatedException("Request queue was cleared")));323        bus.fire(new NewSessionRejectedEvent(324          new NewSessionErrorResponse(reqId, "New session queue was forcibly cleared")));325      });326      requests.clear();327      return size;328    } finally {329      writeLock.unlock();330    }331  }332  @Override333  public List<SessionRequestCapability> getQueueContents() {334    Lock readLock = lock.readLock();335    readLock.lock();336    try {337      return queue.stream()338        .map(req ->339          new SessionRequestCapability(req.getRequestId(), req.getDesiredCapabilities()))340        .collect(Collectors.toList());341    } finally {342      readLock.unlock();343    }344  }345  @ManagedAttribute(name = "NewSessionQueueSize")346  public int getQueueSize() {347    return queue.size();348  }349  @Override350  public boolean isReady() {351    return true;352  }353  @Override...Source:Grid.java  
...52    NewSessionQueue sessionQueue = Require.nonNull("New session queue", newSessionQueue);53    this.queueInfoList = sessionQueue54      .getQueueContents()55      .stream()56      .map(SessionRequestCapability::getDesiredCapabilities)57      .collect(Collectors.toList());58    this.distributorStatus = Suppliers.memoize(distributor::getStatus);59    this.version = Require.nonNull("Grid's version", version);60  }61  public URI getUri() {62    return uri;63  }64  public String getVersion() {65    return version;66  }67  public List<Node> getNodes() {68    ImmutableList.Builder<Node> toReturn = ImmutableList.builder();69    for (NodeStatus status : distributorStatus.get().getNodes()) {70      Map<Capabilities, Integer> stereotypes = new HashMap<>();...Source:SessionRequestCapability.java  
...42  }43  public RequestId getRequestId() {44    return requestId;45  }46  public Set<Capabilities> getDesiredCapabilities() {47    return desiredCapabilities;48  }49  @Override50  public String toString() {51    return new StringJoiner(", ", SessionRequestCapability.class.getSimpleName() + "[", "]")52      .add("requestId=" + requestId)53      .add("desiredCapabilities=" + desiredCapabilities)54      .toString();55  }56  @Override57  public boolean equals(Object o) {58    if (!(o instanceof SessionRequestCapability)) {59      return false;60    }...getDesiredCapabilities
Using AI Code Generation
1import org.openqa.selenium.grid.data.SessionRequestCapability;2import org.openqa.selenium.grid.data.SessionRequest;3import org.openqa.selenium.grid.config.Config;4import org.openqa.selenium.grid.config.MemoizedConfig;5import org.openqa.selenium.grid.config.TomlConfig;6import org.openqa.selenium.grid.data.Session;7import org.openqa.selenium.grid.data.SessionId;8import org.openqa.selenium.grid.data.Slot;9import org.openqa.selenium.grid.data.SlotId;10import org.openqa.selenium.grid.distributor.Distributor;11import org.openqa.selenium.grid.node.local.LocalNode;12import org.openqa.selenium.grid.sessionmap.config.SessionMapOptions;13import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;14import org.openqa.selenium.grid.web.Routable;15import org.openqa.selenium.grid.web.Values;16import org.openqa.selenium.internal.Require;17import org.openqa.selenium.json.Json;18import org.openqa.selenium.remote.http.HttpRequest;19import org.openqa.selenium.remote.http.HttpResponse;20import org.openqa.selenium.remote.tracing.Tracer;21import org.openqa.selenium.remote.tracing.global.GlobalTracer;22import java.io.IOException;23import java.io.UncheckedIOException;24import java.net.URI;25import java.net.URISyntaxException;26import java.time.Duration;27import java.util.Map;28import java.util.Objects;29import java.util.Optional;30import java.util.UUID;31import java.util.function.Function;32import java.util.logging.Logger;33import static org.openqa.selenium.grid.data.Availability.DOWN;34import static org.openqa.selenium.grid.data.Availability.UP;35import static org.openqa.selenium.grid.data.CreateSessionResponse.newSessionResponse;36import static org.openqa.selenium.grid.web.Routes.combine;37import static org.openqa.selenium.remote.http.Contents.asJson;38import static org.openqa.selenium.remote.http.Contents.string;39import static org.openqa.selenium.remote.http.HttpMethod.GET;40import static org.openqa.selenium.remote.http.HttpMethod.POST;41public class MyDistributor implements Distributor {42  private static final Logger LOG = Logger.getLogger(MyDistributor.class.getName());43  private static final Json JSON = new Json();44  private final LocalSessionMap sessions;45  private final LocalNode node;46  public MyDistributor(Tracer tracer, LocalSessionMap sessions, LocalNode node) {47    this.sessions = Require.nonNull("Session map", sessions);48    this.node = Require.nonNull("Node", node);49  }50  public Optional<Slot> getSlot(SessionRequest sessionRequest) {51    if (sessionRequest.getCapabilities().containsKey("browserName")) {52      return node.getSlots().stream()53          .filter(slot -> slot.getCapabilitiesgetDesiredCapabilities
Using AI Code Generation
1import org.openqa.selenium.grid.data.SessionRequestCapability;2import org.openqa.selenium.json.Json;3import org.openqa.selenium.json.JsonException;4import org.openqa.selenium.json.JsonInput;5import org.openqa.selenium.json.JsonOutput;6import java.io.IOException;7import java.io.StringReader;8import java.io.StringWriter;9import java.util.Map;10public class SessionRequestCapabilityTest {11    public static void main(String[] args) throws IOException {12        SessionRequestCapability sessionRequestCapability = new SessionRequestCapability("browserName", "chrome");13        Json json = new Json();14        StringWriter writer = new StringWriter();15        JsonOutput out = json.newOutput(writer);16        out.write(sessionRequestCapability);17        out.close();18        System.out.println(writer);19        StringReader reader = new StringReader(writer.toString());20        JsonInput in = json.newInput(reader);21        Map<String, Object> objectMap = in.read(Map.class);22        in.close();23        System.out.println(objectMap);24    }25}26{"browserName":"chrome"}27{browserName=chrome}getDesiredCapabilities
Using AI Code Generation
1package com.grid;2import java.net.URL;3import org.openqa.selenium.Capabilities;4import org.openqa.selenium.MutableCapabilities;5import org.openqa.selenium.WebDriver;6import org.openqa.selenium.remote.RemoteWebDriver;7import org.openqa.selenium.remote.SessionId;8import org.openqa.selenium.remote.http.HttpClient;9import org.openqa.selenium.remote.http.HttpRequest;10import org.openqa.selenium.remote.http.HttpResponse;11import org.openqa.selenium.remote.http.JsonHttpCommandCodec;12import org.openqa.selenium.remote.http.JsonHttpResponseCodec;13import org.openqa.selenium.remote.http.W3CHttpCommandCodec;14import org.openqa.selenium.remote.http.W3CHttpResponseCodec;15import org.openqa.selenium.remote.internal.ApacheHttpClient;16import org.openqa.selenium.remote.internal.OkHttpClient;17public class TestGrid {18    public static void main(String[] args) throws Exception {19        HttpClient.Factory factory = new ApacheHttpClient.Factory();20        W3CHttpCommandCodec commandCodec = new W3CHttpCommandCodec();21        W3CHttpResponseCodec responseCodec = new W3CHttpResponseCodec();22        MutableCapabilities capabilities = new MutableCapabilities();23        capabilities.setCapability("browserName", "chrome");24        HttpRequest request = commandCodec.encode(new HttpRequest("POST", "/session"), capabilities.asMap());25        HttpResponse response = client.execute(request);26        SessionId sessionId = commandCodec.getSessionId(response.getHeaders());27        Capabilities returnedCapabilities = responseCodec.decode(response, sessionId);28        WebDriver driver = new RemoteWebDriver(client, commandCodec, responseCodec, sessionId);29        System.out.println(driver.getTitle());30        driver.quit();31    }32}getDesiredCapabilities
Using AI Code Generation
1DesiredCapabilities caps = new DesiredCapabilities();2caps.setCapability("browserName", "chrome");3caps.setCapability("version", "latest");4caps.setCapability("platform", "windows 10");5caps.setCapability("name", "Selenium Grid Test");6caps.setCapability("build", "Selenium Grid Test");7caps.setCapability("browserstack.local", "true");8caps.setCapability("browserstack.selenium_version", "3.14.0");9caps.setCapability("browserstack.debug", "true");10caps.setCapability("browserstack.networkLogs", "true");11caps.setCapability("browserstack.console", "errors");12caps.setCapability("browserstack.video", "true");13caps.setCapability("browserstack.timezone", "GMT+05:30");14caps.setCapability("browserstack.seleniumLogs", "true");15caps.setCapability("browserstack.seleniumLogs", "true");16caps.setCapability("browserstack.idleTimeout", "300");17caps.setCapability("browserstack.user", "BROWSERSTACK_USERNAME");18caps.setCapability("browserstack.key", "BROWSERSTACK_ACCESS_KEY");19caps.setCapability("browserstack.appium_version", "1.14.0");20caps.setCapability("browserstack.localIdentifier", "Test123");21caps.setCapability("browserstack.seleniumLogs", "true");22caps.setCapability("browserstack.seleniumLogs", "true");23caps.setCapability("browserstack.seleniumLogs", "true");24caps.setCapability("browserstack.seleniumLogs", "true");25caps.setCapability("browserstack.seleniumLogs", "true");26caps.setCapability("browserstack.seleniumLogs", "true");27caps.setCapability("browserstack.seleniumLogs", "true");28caps.setCapability("browserstack.seleniumLogs", "true");29caps.setCapability("browserstack.seleniumLogs", "true");30caps.setCapability("browserstack.seleniumLogs", "true");31caps.setCapability("browserstack.seleniumLogs", "true");32caps.setCapability("browserstack.seleniumLogs", "true");33caps.setCapability("browserstack.seleniumLogs", "true");34caps.setCapability("browserstack.seleniumLogs", "true");35caps.setCapability("browserstack.seleniumLogs", "true");36caps.setCapability("browserstack.seleniumLogs", "true");37caps.setCapability("browserstack.seleniumLogs", "true");38caps.setCapability("browserstack.seleniumLogs", "true");39caps.setCapability("browserstack.seleniumLogs", "true");40caps.setCapability("browserstack.seleniumLogs", "true");41caps.setCapability("browserstack.seleniumLogs", "true");getDesiredCapabilities
Using AI Code Generation
1import org.openqa.selenium.grid.data.SessionRequestCapability;2import org.openqa.selenium.remote.DesiredCapabilities;3public class SessionRequestCapabilityExample {4  public static void main(String[] args) {5    DesiredCapabilities desiredCapabilities = new DesiredCapabilities();6    desiredCapabilities.setCapability("browserName", "firefox");7    SessionRequestCapability sessionRequestCapability = new SessionRequestCapability(desiredCapabilities);8    System.out.println(sessionRequestCapability.getDesiredCapabilities());9    sessionRequestCapability.setDesiredCapabilities(desiredCapabilities);10  }11}12{browserName=firefox}13{browserName=firefox}LambdaTest’s Selenium 4 tutorial is covering every aspects of Selenium 4 testing with examples and best practices. Here you will learn basics, such as how to upgrade from Selenium 3 to Selenium 4, to some advanced concepts, such as Relative locators and Selenium Grid 4 for Distributed testing. Also will learn new features of Selenium 4, such as capturing screenshots of specific elements, opening a new tab or window on the browser, and new protocol adoptions.
Upgrading From Selenium 3 To Selenium 4?: In this chapter, learn in detail how to update Selenium 3 to Selenium 4 for Java binding. Also, learn how to upgrade while using different build tools such as Maven or Gradle and get comprehensive guidance for upgrading Selenium.
What’s New In Selenium 4 & What’s Being Deprecated? : Get all information about new implementations in Selenium 4, such as W3S protocol adaption, Optimized Selenium Grid, and Enhanced Selenium IDE. Also, learn what is deprecated for Selenium 4, such as DesiredCapabilites and FindsBy methods, etc.
Selenium 4 With Python: Selenium supports all major languages, such as Python, C#, Ruby, and JavaScript. In this chapter, learn how to install Selenium 4 for Python and the features of Python in Selenium 4, such as Relative locators, Browser manipulation, and Chrom DevTool protocol.
Selenium 4 Is Now W3C Compliant: JSON Wireframe protocol is retiring from Selenium 4, and they are adopting W3C protocol to learn in detail about the advantages and impact of these changes.
How To Use Selenium 4 Relative Locator? : Selenium 4 came with new features such as Relative Locators that allow constructing locators with reference and easily located constructors nearby. Get to know its different use cases with examples.
Selenium Grid 4 Tutorial For Distributed Testing: Selenium Grid 4 allows you to perform tests over different browsers, OS, and device combinations. It also enables parallel execution browser testing, reads up on various features of Selenium Grid 4 and how to download it, and runs a test on Selenium Grid 4 with best practices.
Selenium Video Tutorials: Binge on video tutorials on Selenium by industry experts to get step-by-step direction from automating basic to complex test scenarios with Selenium.
LambdaTest also provides certification for Selenium testing to accelerate your career in Selenium automation testing.
Get 100 minutes of automation test minutes FREE!!
