How to use toJson method of org.openqa.selenium.remote.Interface Browser class

Best Selenium code snippet using org.openqa.selenium.remote.Interface Browser.toJson

Source:HtmlElement.java Github

copy

Full Screen

...1633 findElement(false, false);1634 return ((Locatable)element).getCoordinates();1635 }1636 1637 public Map<String, Object> toJson() {1638 findElement();1639 return ((RemoteWebElement)getUnderlyingElement(element)).toJson();1640 }1641 1642 public HtmlElement getParent() {1643 return parent;1644 }16451646 public void setParent(HtmlElement parent) {1647 this.parent = parent;1648 }16491650 public void setBy(By by) {1651 this.by = by;1652 }1653 ...

Full Screen

Full Screen

Source:AgentClient.java Github

copy

Full Screen

...544 private void startSession(final Capabilities capabilities, final ReportSettings reportSettings)545 throws InvalidTokenException, AgentConnectException, ObsoleteVersionException, MissingBrowserException,546 DeviceNotConnectedException {547 LOG.info("Initializing new session...");548 LOG.trace("Initializing new session with capabilities: {}", GSON.toJson(capabilities));549 // Extract TP_GUID capability550 String guid = Objects.requireNonNull(capabilities.getCapability(TP_GUID)).toString();551 // Initialize POST request to Agent API552 HttpPost httpPost = new HttpPost(remoteAddress + Routes.DEVELOPMENT_SESSION);553 // New session initialization can take up to 120s554 // This is why this config is unique and other calls use getDefaultConfig() method555 RequestConfig config = RequestConfig.custom()556 .setConnectionRequestTimeout(CONNECTION_TIMEOUT_MS)557 .setConnectTimeout(CONNECTION_TIMEOUT_MS)558 .setSocketTimeout(NEW_SESSION_SOCKET_TIMEOUT_MS)559 .build();560 httpPost.setConfig(config);561 // Prepare Payload562 SessionRequest request = new SessionRequest(reportSettings, capabilities.asMap());563 // Save report settings564 this.projectName = request.getProjectName();565 this.jobName = request.getJobName();566 StringEntity entity = new StringEntity(GSON.toJson(request), StandardCharsets.UTF_8);567 httpPost.setEntity(entity);568 // Send POST request569 CloseableHttpResponse response;570 try {571 response = httpClient.execute(httpPost);572 } catch (IOException e) {573 throw translateAgentConnectFailure(e);574 }575 // Handle unsuccessful response (not 2xx)576 if (response.getStatusLine().getStatusCode() < HttpURLConnection.HTTP_OK577 || response.getStatusLine().getStatusCode() >= HttpURLConnection.HTTP_MULT_CHOICE) {578 handleSessionStartFailure(response, capabilities);579 return;580 }581 // Read Response582 String responseBody;583 try {584 responseBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8.name());585 } catch (IOException e) {586 LOG.error("Failed reading Agent response", e);587 throw new AgentConnectException("Failed reading Agent response", e);588 }589 LOG.trace("Session initialization response: {}", responseBody);590 try {591 agentResponse = GSON.fromJson(responseBody, SessionResponse.class);592 } catch (JsonSyntaxException e) {593 LOG.error("Failed to parse Agent response", e);594 throw new AgentConnectException("Failed to parse Agent response", e);595 }596 LOG.info("Session [{}] initialized", agentResponse.getSessionId());597 // Process Response598 try {599 MutableCapabilities mutableCapabilities;600 if (agentResponse.getCapabilities() != null) {601 mutableCapabilities = new MutableCapabilities(agentResponse.getCapabilities());602 } else {603 mutableCapabilities = new MutableCapabilities();604 }605 // There's a chance that driver ignored our custom tracking capability606 // And now does't return it with the actual driver capabilities607 // It has to be set again to avoid initializing an new AgentClient instance for these capabilities again608 mutableCapabilities.setCapability(TP_GUID, guid);609 version = agentResponse.getVersion();610 // Set the server URL to null if using the Generic driver.611 URL serverUrl = ((capabilities.getPlatform() == Platform.ANY) ? null612 : new URL(agentResponse.getServerAddress()));613 this.session = new AgentSession(614 serverUrl,615 !StringUtils.isEmpty(agentResponse.getSessionId())616 ? agentResponse.getSessionId() : UUID.randomUUID().toString(),617 agentResponse.getDialect() != null618 ? Dialect.valueOf(agentResponse.getDialect()) : null,619 mutableCapabilities);620 } catch (MalformedURLException e) {621 LOG.error("Agent returned an invalid server URL: [{}]", agentResponse.getServerAddress(), e);622 throw new AgentConnectException("Failed initializing a session", e);623 }624 // Open TCP socket625 SocketManager.getInstance().openSocket(this.remoteAddress.getHost(), agentResponse.getDevSocketPort());626 }627 /**628 * Translates an IOException to an informative exception.629 * @param e the original exception630 * @return the translated exception631 */632 private AgentConnectException translateAgentConnectFailure(final IOException e) {633 Throwable rootCause = ExceptionUtils.getRootCause(e);634 if (SocketTimeoutException.class.isAssignableFrom(rootCause.getClass())) {635 return new AgentConnectException("Could not complete the request to start a new session. "636 + "Another program such as an antivirus/firewall seems to be interfering with the connection.");637 }638 if (ConnectException.class.isAssignableFrom(rootCause.getClass())) {639 return new AgentConnectException("Could not connect to agent. "640 + "Please make sure it is running and try again");641 }642 return new AgentConnectException("Failed communicating with the Agent at " + this.remoteAddress, e);643 }644 /**645 * Infer Project and Job names from call stack.646 *647 * @param reportSettings Project and Job names provided explicitly.648 * @return {@link ReportSettings} instance with discovered Project and Job names.649 */650 private ReportSettings inferReportSettings(final ReportSettings reportSettings) {651 if (reportSettings != null652 && !StringUtils.isEmpty(reportSettings.getProjectName())653 && !StringUtils.isEmpty(reportSettings.getJobName())) {654 LOG.trace("Project and Job names were explicitly set, skipping inferring.");655 return reportSettings;656 }657 LOG.trace("Report settings were not provided or incomplete, trying to infer...");658 // Grab stack traces to analyze callers and infer Project/Job names659 List<StackTraceElement> traces = Arrays.asList(Thread.currentThread().getStackTrace());660 // Try to infer Project and Job names from Unit Testing FWs annotations661 ReportSettings inferredReportSettings = InferrerFactory.getInferrer(traces).inferReportSettings();662 // Inferrer returned empty ReportSettings663 if (inferredReportSettings == null) {664 inferredReportSettings = new GenericInferrer(traces).inferReportSettings();665 }666 LOG.info("Inferred [{}] and [{}] for Project and Job names accordingly.",667 inferredReportSettings.getProjectName(), inferredReportSettings.getJobName());668 ReportSettings result;669 if (reportSettings != null) {670 // Explicitly provided names override inferred names671 // Explicitly requested report type must be honored672 result = new ReportSettings(673 !StringUtils.isEmpty(reportSettings.getProjectName())674 ? reportSettings.getProjectName() : inferredReportSettings.getProjectName(),675 !StringUtils.isEmpty(reportSettings.getJobName())676 ? reportSettings.getJobName() : inferredReportSettings.getJobName(),677 reportSettings.getReportType());678 } else {679 // Nothing provided, using only inferred names680 result = inferredReportSettings;681 }682 LOG.info("Using [{}] and [{}] for Project and Job names accordingly.",683 result.getProjectName(), result.getJobName());684 if (Boolean.getBoolean("TP_DISABLE_AUTO_REPORTS")) {685 skipInferring = true;686 }687 return result;688 }689 /**690 * Verify that target Agent supports local reports, otherwise throw an exception.691 * @param reportType Report type requested.692 * @throws AgentConnectException when local reports are not supported.693 */694 private void verifyLocalReportsSupported(final ReportType reportType) throws AgentConnectException {695 if (reportType == ReportType.LOCAL && new ComparableVersion(version).compareTo(696 new ComparableVersion(MIN_LOCAL_REPORT_SUPPORTED_VERSION)) < 0) {697 StringBuilder message = new StringBuilder()698 .append("Target Agent version").append(" [").append(version).append("] ")699 .append("doesn't support local reports. ")700 .append("Upgrade the Agent to the latest version and try again.");701 throw new AgentConnectException(message.toString());702 }703 }704 /**705 * Handle a scenario when Agent session initialization fails.706 *707 * @param response Response to the RESTful endpoint call sent to Agent708 * @param capabilities capabilities with requested driver details.709 * @throws AgentConnectException if Agent is not responding or responds with an error710 * @throws InvalidTokenException if the token provided is invalid711 * @throws ObsoleteVersionException if the SDK version is incompatible with the Agent712 * @throws MissingBrowserException if the requested browser is not installed.713 * @throws DeviceNotConnectedException if the requested device is not found.714 */715 private void handleSessionStartFailure(final CloseableHttpResponse response, final Capabilities capabilities)716 throws InvalidTokenException, ObsoleteVersionException, AgentConnectException, MissingBrowserException,717 DeviceNotConnectedException {718 String statusMessage = null;719 try {720 String responseBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8.name());721 JsonObject json = (JsonObject) new JsonParser().parse(responseBody);722 JsonElement message = json.get("message");723 statusMessage = message != null && !message.isJsonNull() ? message.getAsString() : null;724 } catch (IOException e) {725 LOG.error("Failed reading Agent response", e);726 }727 // Inspect Response Status Code728 switch (response.getStatusLine().getStatusCode()) {729 case HttpURLConnection.HTTP_UNAUTHORIZED:730 LOG.error("Failed to initialize a session with the Agent - token is invalid");731 throw new InvalidTokenException();732 case HttpURLConnection.HTTP_NOT_ACCEPTABLE:733 LOG.error("Failed to initialize a session with the Agent - obsolete SDK version");734 throw new ObsoleteVersionException(statusMessage);735 case HttpURLConnection.HTTP_NOT_FOUND:736 if (statusMessage != null && capabilities.getBrowserName().equals("")) {737 LOG.error("Failed to initialize a session with the Agent - Requested device is not connected");738 throw new DeviceNotConnectedException();739 }740 LOG.error("Failed to initialize a session with the Agent - requested browser is not installed");741 throw new MissingBrowserException();742 default:743 LOG.error("Failed to initialize a session with the Agent");744 throw new AgentConnectException("Agent responded with status "745 + response.getStatusLine().getStatusCode() + ": [" + statusMessage + "]");746 }747 }748 /**749 * Getter for {@link #session} field.750 *751 * @return value of {@link #session} field752 */753 public AgentSession getSession() {754 return session;755 }756 /**757 * Getter for {@link #version} field.758 *759 * @return value of {@link #version} field760 */761 public String getVersion() {762 return version;763 }764 /**765 * Getter for {@link #projectName}.766 *767 * @return value of {@link #projectName} field768 */769 public String getProjectName() {770 return this.projectName;771 }772 /**773 * Getter for {@link #jobName}.774 *775 * @return value of {@link #jobName} field776 */777 public String getJobName() {778 return this.jobName;779 }780 /**781 * Getter for {@link #projectName} and {@link #jobName} as {@link ReportSettings}.782 *783 * @return value of {@link #projectName} and {@link #jobName} fields wrapped in {@link ReportSettings}784 */785 public ReportSettings getReportSetting() {786 if (StringUtils.isEmpty(projectName) || StringUtils.isEmpty(jobName)) {787 return null;788 }789 return new ReportSettings(this.projectName, this.jobName);790 }791 /**792 * Getter for {@link #skipInferring field}.793 * Used to check if the report settings were explicitly set.794 *795 * @return true if the report settings were inferred, false otherwise.796 */797 public boolean getSkipInferring() {798 return skipInferring;799 }800 /**801 * Getter for {@link #reportsDisabled field}.802 * Used to check if the reports were explicitly disabled.803 *804 * @return true if the reports were disabled.805 */806 public boolean getReportsDisabled() {807 return reportsDisabled;808 }809 /**810 * Getter for {@link #warned field}.811 *812 * @return true if warned once the client is null.813 */814 public static boolean isWarned() {815 return warned;816 }817 /**818 * Removes shutdown hook and calls {@link #close()}.819 */820 private void stop() {821 ShutdownThreadManager.getInstance().removeAgentClient();822 LOG.trace("Removed shutdown thread to avoid unnecessary close() calls");823 close();824 }825 /**826 * Implementation of {@link Closeable Closable} interface.827 * Closes all open resources such as the reporting queue without closing828 * the TCP socket open with the agent.829 */830 public void close() {831 close(false);832 }833 /**834 * Close all open resources such as the reporting queue and the TCP socket open with the Agent835 * if the process is exiting.836 *837 * @param exiting used to determine if the socket should be closed.838 */839 public void close(final boolean exiting) {840 LOG.trace("Closing AgentClient for driver session [{}]", this.getSession().getSessionId());841 if (reportsQueueFuture != null && !reportsQueueFuture.isDone()) {842 reportsQueue.stop();843 try {844 reportsQueueFuture.get(REPORTS_QUEUE_TIMEOUT, TimeUnit.SECONDS);845 } catch (InterruptedException e) {846 LOG.error("Reports queue was interrupted while sending reports.");847 } catch (ExecutionException e) {848 LOG.error("Reports queue has thrown an exception", ExceptionUtils.getRootCause(e));849 } catch (TimeoutException e) {850 LOG.error("Reports queue didn't finish uploading reports in a timely manner and was terminated.");851 }852 if (!reportsQueueFuture.isDone()) {853 LOG.warn("Terminating reports queue forcibly...");854 reportsQueueFuture.cancel(true);855 }856 }857 if (!reportsExecutorService.isTerminated()) {858 reportsExecutorService.shutdown();859 }860 // Make sure to close the socket when exiting.861 if (exiting) {862 LOG.debug("Agent client is closing development socket as process is exiting...");863 SocketManager.getInstance().closeSocket();864 }865 LOG.info("Session [{}] closed", this.getSession().getSessionId());866 if (!StringUtils.isEmpty(agentResponse.getLocalReport())) {867 LOG.info("Execution Report: {}", agentResponse.getLocalReport());868 }869 }870 /**871 * Reports a driver command execution to the Agent.872 *873 * @param command Command executed by the driver.874 * @param result Command result formatted as String875 * @param passed Boolean flag to indicate command successful execution or failure.876 * @param screenshot Screenshot as base64 string.877 * @return True if successfully reported, otherwise False.878 */879 public boolean reportCommand(final Command command,880 final Object result,881 final boolean passed,882 final String screenshot) {883 // Initialize POST request to Agent API884 HttpPost httpPost = new HttpPost(remoteAddress + Routes.REPORT_COMMAND);885 httpPost.setConfig(getDefaultHttpConfig());886 // Prepare payload887 DriverCommandReport report =888 new DriverCommandReport(command.getName(), command.getParameters(), result, passed);889 // Set screenshot into report when provided890 if (screenshot != null) {891 report.setScreenshot(screenshot);892 }893 String json;894 try {895 json = GSON.toJson(report);896 } catch (Exception e) {897 return false;898 }899 StringEntity entity = new StringEntity(json, StandardCharsets.UTF_8);900 httpPost.setEntity(entity);901 // Send POST request902 this.reportsQueue.submit(httpPost, report);903 return true;904 }905 /**906 * Reports a step to the Agent.907 *908 * @param report Report to submit.909 * @return True is successful, otherwise False.910 */911 public boolean reportStep(final StepReport report) {912 // Initialize POST request to Agent API913 HttpPost httpPost = new HttpPost(remoteAddress + Routes.REPORT_STEP);914 httpPost.setConfig(getDefaultHttpConfig());915 // Prepare payload916 StringEntity entity = new StringEntity(GSON.toJson(report), StandardCharsets.UTF_8);917 httpPost.setEntity(entity);918 // Send POST request919 this.reportsQueue.submit(httpPost, report);920 return true;921 }922 /**923 * Reports a test to the Agent.924 *925 * @param report Report to submit.926 * @return True is successful, otherwise False.927 */928 public boolean reportTest(final TestReport report) {929 // Initialize POST request to Agent API930 HttpPost httpPost = new HttpPost(remoteAddress + Routes.REPORT_TEST);931 httpPost.setConfig(getDefaultHttpConfig());932 // Prepare payload933 StringEntity entity = new StringEntity(GSON.toJson(report), StandardCharsets.UTF_8);934 httpPost.setEntity(entity);935 // Send POST request936 this.reportsQueue.submit(httpPost, report);937 return true;938 }939 /**940 * Executes a Action proxy from an Addon installed in an Account.941 *942 * @param action An instance of an action that extends the {@link ActionProxy} class.943 * @param timeout maximum amount of time allowed to wait for action execution to complete.944 * @return Execution result in form of {@link ActionExecutionResponse}.945 * @throws WebDriverException when execution fails.946 */947 public ActionExecutionResponse executeProxy(final ActionProxy action, final int timeout) throws WebDriverException {948 // Initialize POST request to Agent API949 HttpPost httpPost = new HttpPost(remoteAddress + Routes.EXECUTE_ACTION_PROXY);950 // Addon execution can take time,951 // This is why this config is unique and other calls use getDefaultConfig() method952 RequestConfig config = RequestConfig.custom()953 .setConnectionRequestTimeout(CONNECTION_TIMEOUT_MS)954 .setConnectTimeout(CONNECTION_TIMEOUT_MS)955 .setSocketTimeout(timeout > 0 ? timeout : ADDON_EXECUTION_SOCKET_TIMEOUT_MS)956 .build();957 httpPost.setConfig(config);958 // Action fields should be provided as ProxyDescriptor parameters.959 // Using Gson as a workaround to create a HashMap of objects declared fields.960 @SuppressWarnings("unchecked") // Using raw type as can't specify generic parameters for Gson961 HashMap<String, Object> parameters = GSON.fromJson(GSON.toJsonTree(action).toString(), HashMap.class);962 action.getDescriptor().setParameters(parameters);963 // Prepare payload964 String request = GSON.toJson(action.getDescriptor());965 LOG.trace("Sending action proxy request: {}", request);966 StringEntity entity = new StringEntity(request, StandardCharsets.UTF_8);967 httpPost.setEntity(entity);968 // Send POST request969 CloseableHttpResponse response;970 try {971 response = this.httpClient.execute(httpPost);972 } catch (IOException e) {973 LOG.error("Failed to execute action proxy: [{}]", action, e);974 throw new WebDriverException("Failed to execute action proxy: [" + action + "]", e);975 }976 // Handle unsuccessful response977 if (response != null && response.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_OK) {978 LOG.error("Agent responded with an unexpected status {} to action proxy execution: [{}]",979 response.getStatusLine().getStatusCode(), action);980 }981 if (response == null) {982 LOG.error("Agent response is empty");983 throw new WebDriverException("Failed to execute action proxy: [" + action + "]");984 }985 // Read Response986 String responseBody;987 try {988 responseBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8.name());989 } catch (IOException e) {990 LOG.error("Failed reading action proxy execution response", e);991 throw new WebDriverException("Failed reading action proxy execution response", e);992 }993 try {994 return GSON.fromJson(responseBody, ActionExecutionResponse.class);995 } catch (JsonSyntaxException e) {996 LOG.error("Failed reading action proxy execution response", e);997 throw new WebDriverException("Failed reading action proxy execution response", e);998 }999 }1000 /**1001 * Sent request to Agent API to update job name at runtime.1002 *1003 * @param updatedJobName to update original with.1004 */1005 public void updateJobName(final String updatedJobName) {1006 // Initialize PUT request to Agent API to override configuration.1007 HttpPut httpPut = new HttpPut(remoteAddress + AgentClient.Routes.DEVELOPMENT_SESSION);1008 httpPut.setConfig(getDefaultHttpConfig());1009 SessionRequest request = new SessionRequest(updatedJobName);1010 // Prepare payload1011 String data = GSON.toJson(request);1012 LOG.trace("Sending request to update job name to: {}", data);1013 StringEntity entity = new StringEntity(data, StandardCharsets.UTF_8);1014 httpPut.setEntity(entity);1015 // Send PUT request1016 CloseableHttpResponse response;1017 try {1018 response = this.httpClient.execute(httpPut);1019 } catch (IOException e) {1020 LOG.error("Failed to execute request to update job name: [{}]", updatedJobName, e);1021 return;1022 }1023 if (response.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_OK) {1024 LOG.error("Failed to update job name to {}", updatedJobName);1025 }...

Full Screen

Full Screen

Source:JBrowserDriver.java Github

copy

Full Screen

...1343 Map<String, Object> emptyPauseAction = ImmutableMap.of("duration", 0L, "type", "pause");13441345 EnumMap<SourceType, List<Map<String, Object>>> mappedActions = new EnumMap<>(SourceType.class);1346 for (Sequence sequence : actions) {1347 Map<String, Object> sequenceValues = sequence.toJson();1348 SourceType sourceType = SourceType.valueOf(((String) sequenceValues.get("type")).toUpperCase());1349 mappedActions.put(sourceType, (List<Map<String, Object>>) sequenceValues.get("actions"));1350 }13511352 Element lastProcessedElement = null;1353 int sequenceSize = mappedActions.values().iterator().next().size();1354 for (int cursor = 0; cursor < sequenceSize; cursor++) {1355 int counter = 0;1356 for (Map.Entry<SourceType, List<Map<String, Object>>> actionEntry : mappedActions.entrySet()) {1357 Map<String, Object> action = actionEntry.getValue().get(cursor);1358 if (!emptyPauseAction.equals(action)) {1359 String actionType = (String) action.get("type");1360 Object executor = chooseExecutor(actionEntry.getKey());1361 lastProcessedElement = W3CActions.findActionByType(actionType).perform(executor, lastProcessedElement, ...

Full Screen

Full Screen

Source:CustomRemoteProxy.java Github

copy

Full Screen

...157 JsonObject map = new JsonParser().parse(body).getAsJsonObject();158 boolean bodyChanged = false;159 if (map.has("capabilities")) {160 map.getAsJsonObject("capabilities").remove("desiredCapabilities");161 map.getAsJsonObject("capabilities").add("desiredCapabilities", new JsonParser().parse(new Gson().toJson(session.getRequestedCapabilities())).getAsJsonObject());162 bodyChanged = true;163 }164 if (map.has("desiredCapabilities")) {165 map.remove("desiredCapabilities");166 map.add("desiredCapabilities", new JsonParser().parse(new Gson().toJson(session.getRequestedCapabilities())).getAsJsonObject());167 bodyChanged = true;168 }169 170 if (bodyChanged) {171 ((SeleniumBasedRequest)request).setBody(map.toString());172 }173174 } catch (JsonSyntaxException | IllegalStateException | UnsupportedEncodingException e) {175 }176 177 // get PID before we create driver178 // use locking so that only one session is created at a time179 if(((SeleniumBasedRequest)request).getRequestType() == RequestType.START_SESSION) {180 beforeStartSession(session);181 }182 183 else if(((SeleniumBasedRequest)request).getRequestType() == RequestType.STOP_SESSION) {184 beforeStopSession(session);185 }186 }187 188189 /**190 * Do something after the START_SESSION and STOP_SESSION commands has been sent191 */192 @Override193 public void afterCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) {194 super.afterCommand(session, request, response);195 196 197 if(((SeleniumBasedRequest)request).getRequestType() == RequestType.START_SESSION) {198 afterStartSession(session); 199 }200 201 else if(((SeleniumBasedRequest)request).getRequestType() == RequestType.STOP_SESSION && session.get(PIDS_TO_KILL) != null) {202 afterStopSession(session);203 }204 }205 206 /**207 * Do actions before test session creation208 * - add device name when doing mobile testing. This will allow to add missing caps, for example when client requests an android device without specifying it precisely209 * - make file available as HTTP URL instead of FILE URL. These files must have already been uploaded to grid hub210 * 211 */212 @Override213 public void beforeSession(TestSession session) {214 215 if (!isBusyOnOtherSlots(session)) {216 cleanNode();217 }218 219 // add firefox & chrome binary to caps220 super.beforeSession(session);221 boolean mobilePlatform = false;222 Map<String, Object> requestedCaps = session.getRequestedCapabilities();223 224 // update capabilities for mobile. Mobile tests are identified by the use of 'platformName' capability225 // this will allow to add missing caps, for example when client requests an android device without specifying it precisely226 String platformName = (String)requestedCaps.getOrDefault(MobileCapabilityType.PLATFORM_NAME, "nonmobile");227 if (platformName.toLowerCase().contains("ios") || platformName.toLowerCase().contains("android")) {228 mobilePlatform = true;229 try {230 DesiredCapabilities caps = mobileServletClient.updateCapabilities(new DesiredCapabilities(requestedCaps));231 requestedCaps.putAll(caps.asMap());232 } catch (IOException | URISyntaxException e) {233 }234 235 try {236 String appiumUrl = nodeClient.startAppium(session.getInternalKey());237 requestedCaps.put("appiumUrl", appiumUrl);238 } catch (UnirestException e) {239 throw new ConfigurationException("Could not start appium: " + e.getMessage());240 }241 }242243 // replace all capabilities whose value begins with 'file:' by the remote HTTP URL244 // we assume that these files have been previously uploaded on hub and thus available245 for (Entry<String, Object> entry: session.getRequestedCapabilities().entrySet()) {246 if (entry.getValue() instanceof String && ((String)entry.getValue()).startsWith(FileServlet.FILE_PREFIX)) {247 requestedCaps.put(entry.getKey(), String.format("http://%s:%s/grid/admin/FileServlet/%s", 248 getConfig().getHubHost(), 249 getConfig().getHubPort(), 250 ((String)entry.getValue()).replace(FileServlet.FILE_PREFIX, "")));251 }252 }253 254 // set marionette mode depending on firefox version255 Map<String, Object> nodeCapabilities = session.getSlot().getCapabilities();256 if (nodeCapabilities.get(CapabilityType.BROWSER_NAME) != null 257 && nodeCapabilities.get(CapabilityType.BROWSER_NAME).equals(BrowserType.FIREFOX.toString().toLowerCase())258 && nodeCapabilities.get(CapabilityType.BROWSER_VERSION) != null) {259 260 if (Float.parseFloat((String)nodeCapabilities.get(CapabilityType.BROWSER_VERSION)) < 47.9) {261 requestedCaps.put("marionette", false);262 } else {263 requestedCaps.put("marionette", true);264 }265 }266267 // add driver path if it's present in node capabilities, so that they can be transferred to node268 if (nodeCapabilities.get(CapabilityType.BROWSER_NAME) != null) {269 try {270 if (nodeCapabilities.get(CapabilityType.BROWSER_NAME).toString().toLowerCase().contains(BrowserType.CHROME.toLowerCase()) && nodeCapabilities.get(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY) != null) {271 updateChromeCapabilities(requestedCaps, nodeCapabilities);272 273 } else if (nodeCapabilities.get(CapabilityType.BROWSER_NAME).toString().toLowerCase().contains(BrowserType.FIREFOX.toLowerCase()) && nodeCapabilities.get(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY) != null) {274 updateFirefoxCapabilities(requestedCaps, nodeCapabilities);275 276 } else if (nodeCapabilities.get(CapabilityType.BROWSER_NAME).toString().toLowerCase().contains(BrowserType.IE.toLowerCase()) && nodeCapabilities.get(InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY) != null) {277 updateInternetExplorerCapabilities(requestedCaps, nodeCapabilities);278 279 } else if (nodeCapabilities.get(CapabilityType.BROWSER_NAME).toString().toLowerCase().contains(BrowserType.EDGE.toLowerCase()) && nodeCapabilities.get(EdgeDriverService.EDGE_DRIVER_EXE_PROPERTY) != null) {280 updateEdgeCapabilities(requestedCaps, nodeCapabilities);281 }282 } catch (UnirestException e) {283 throw new ConfigurationException("Could not transfer driver path to node, abord: " + e.getMessage());284 }285 }286 287 // remove se:CONFIG_UUID for IE (issue #15) (moved from CustomDriverProvider)288 if (BrowserType.IE.equals(requestedCaps.get(CapabilityType.BROWSER_NAME))) {289 requestedCaps.remove("se:CONFIG_UUID");290 }291 292 // issue #54: set the platform to family platform, not the more precise one as this fails. Platform value may be useless now as test slot has been selected293 if (!mobilePlatform && requestedCaps.get(CapabilityType.PLATFORM) != null && ((Platform)requestedCaps.get(CapabilityType.PLATFORM)).family() != null) {294 Platform pf = (Platform)requestedCaps.remove(CapabilityType.PLATFORM);295 requestedCaps.put(CapabilityType.PLATFORM, pf.family());296 requestedCaps.remove(CapabilityType.PLATFORM_NAME);297 requestedCaps.put(CapabilityType.PLATFORM_NAME, pf.family().toString());298 }299 }300301 /**302 * @param requestedCaps303 * @param nodeCapabilities304 */305 private void updateInternetExplorerCapabilities(Map<String, Object> requestedCaps,306 Map<String, Object> nodeCapabilities) {307 requestedCaps.put(InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY, nodeCapabilities.get(InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY).toString());308 nodeClient.setProperty(InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY, nodeCapabilities.get(InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY).toString());309 310 if (requestedCaps.containsKey(SeleniumRobotCapabilityType.EDGE_IE_MODE) 311 && (boolean) requestedCaps.get(SeleniumRobotCapabilityType.EDGE_IE_MODE) 312 && nodeCapabilities.get(EDGE_PATH) != null) {313314 // put in both location as Selenium3 does not handle edge chromium properly315 requestedCaps.putIfAbsent(SE_IE_OPTIONS, new HashMap<>());316 ((Map<String, Object>) requestedCaps.get(SE_IE_OPTIONS)).put("ie.edgechromium", true);317 requestedCaps.put("ie.edgechromium", true); 318 ((Map<String, Object>) requestedCaps.get(SE_IE_OPTIONS)).put("ie.edgepath", nodeCapabilities.get(EDGE_PATH));319 requestedCaps.put("ie.edgepath", nodeCapabilities.get(EDGE_PATH));320 }321 322 }323 324 /**325 * Update capabilites for firefox, depending on what is requested326 * @param requestedCaps327 * @param nodeCapabilities328 */329 private void updateFirefoxCapabilities(Map<String, Object> requestedCaps, Map<String, Object> nodeCapabilities) {330 requestedCaps.put(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY, nodeCapabilities.get(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY).toString());331 332333 // in case "firefoxProfile" capability is set, add the '--user-data-dir' option. If value is 'default', search the default user profile334 if (requestedCaps.get("firefoxProfile") != null) {335 try {336 // get some options of the current profile337 FirefoxProfile profile = FirefoxProfile.fromJson((String) requestedCaps.get("firefox_profile"));338 String userAgent = profile.getStringPreference("general.useragent.override", null);339 String ntlmTrustedUris = profile.getStringPreference("network.automatic-ntlm-auth.trusted-uris", null);340 341 FirefoxProfile newProfile;342 if (requestedCaps.get("firefoxProfile").equals(BrowserInfo.DEFAULT_BROWSER_PRODFILE)) {343 newProfile = new ProfilesIni().getProfile("default");344 } else {345 newProfile = new FirefoxProfile(new File((String) requestedCaps.get("firefoxProfile")));346 }347 if (userAgent != null) {348 newProfile.setPreference("general.useragent.override", userAgent);349 }350 if (ntlmTrustedUris != null) {351 newProfile.setPreference("network.automatic-ntlm-auth.trusted-uris", ntlmTrustedUris);352 }353 newProfile.setPreference("capability.policy.default.Window.QueryInterface", ALL_ACCESS);354 newProfile.setPreference("capability.policy.default.Window.frameElement.get", ALL_ACCESS);355 newProfile.setPreference("capability.policy.default.HTMLDocument.compatMode.get", ALL_ACCESS);356 newProfile.setPreference("capability.policy.default.Document.compatMode.get", ALL_ACCESS);357 newProfile.setPreference("dom.max_chrome_script_run_time", 0);358 newProfile.setPreference("dom.max_script_run_time", 0);359 requestedCaps.put(FirefoxDriver.PROFILE, newProfile.toJson());360 361 } catch (Exception e) {362 logger.error("Cannot change firefox profile", e);363 }364 }365 366 // issue #60: if "firefox_binary" is set (case of custom / portable browsers), add it to requested caps, else, session is not started367 if (nodeCapabilities.get(FirefoxDriver.BINARY) != null) {368 requestedCaps.put(FirefoxDriver.BINARY, nodeCapabilities.get(FirefoxDriver.BINARY));369 }370 nodeClient.setProperty(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY, nodeCapabilities.get(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY).toString());371 372 }373 ...

Full Screen

Full Screen

Source:CrawData.java Github

copy

Full Screen

...362 for (Element itemTagElement : listAllTagElements) {363 arrayContent.add(itemTagElement.text());364 }365 }366 content = gson.toJson(arrayContent);367 } catch (Exception e) {368 e.printStackTrace();369 }370 }371372 }373 return content;374 }375376 @Override377 public String getTimeCreateOfContent(List<String> nodeTime, Document docDetail) {378 String time = "";379 for (String itemTime : nodeTime) {380 if (!itemTime.equals("")) { ...

Full Screen

Full Screen

Source:DriverManager.java Github

copy

Full Screen

...383 // //url = new URL("http://target_ip:used_port/wd/hub");384 // //if it needs to use locally started server385 // //then the target_ip is 127.0.0.1 or 0.0.0.0386 // //the default port is 4723387 // BFLogger.logDebug("Capabilities: " + capabilities.toJson());388 // newRemoteWebDriver = new NewAppiumDriver(url, capabilities);389 // } catch (MalformedURLException e) {390 // BFLogger.logError("Unable connect to Appium Server URL: " + APPIUM_SERVER_URL);391 // }392 // return newRemoteWebDriver;393 // }394 // };395 //396 //397 //398 // public INewMobileDriver getDriver() {399 // return null;400 // }401 402 }403 404 private interface IDriverManager {405 406 String getUrl();407 408 <T extends NewAppiumDriver> INewMobileDriver getDriver();409 410 DesiredCapabilities getCapabilities();411 }412 413 private static class DriverManagerForAppium implements IDriverManager {414 415 public String getUrl() {416 return RuntimeParameters.DEVICE_URL.getValue() + "/wd/hub";417 }418 419 public DesiredCapabilities getCapabilities() {420 DesiredCapabilities capabilities = new DesiredCapabilities();421 RuntimeParameters[] capsToSet = { RuntimeParameters.AUTOMATION_NAME, RuntimeParameters.PLATFORM_NAME, RuntimeParameters.PLATFORM_VERSION,422 RuntimeParameters.DEVICE_NAME, RuntimeParameters.APP, RuntimeParameters.BROWSER_NAME };423 Arrays.stream(capsToSet)424 .forEach(e -> capabilities.setCapability(e.getKey(), e.getValue()));425 426 // Set users device options427 RuntimeParameters.DEVICE_OPTIONS.getValues()428 .forEach((key, value) -> {429 BFLogger.logInfo("Device option: " + key + " " + value);430 capabilities.setCapability(key, value);431 });432 433 BFLogger.logDebug("Capabilities: " + capabilities.toJson());434 return capabilities;435 }436 437 public INewMobileDriver getDriver() {438 439 BFLogger.logDebug("Connecting to the Appium Server: " + getUrl());440 441 INewMobileDriver newRemoteWebDriver = null;442 try {443 URL url = new URL(getUrl());444 // url = new URL("http://target_ip:used_port/wd/hub");445 // if it needs to use locally started server446 // then the target_ip is 127.0.0.1 or 0.0.0.0447 // the default port is 4723...

Full Screen

Full Screen

Source:SelfRegisteringRemote.java Github

copy

Full Screen

...142 registrationRequest.getConfiguration().host = null;143 registrationRequest.getConfiguration().fixUpHost();144 }145 fixUpId();146 LOG.fine("Using the json request : " + new Json().toJson(registrationRequest));147 Boolean register = registrationRequest.getConfiguration().register;148 if (register == null) {149 register = false;150 }151 if (!register) {152 LOG.info("No registration sent ( register = false )");153 } else {154 final int155 registerCycleInterval =156 registrationRequest.getConfiguration().registerCycle != null ?157 registrationRequest.getConfiguration().registerCycle : 0;158 if (registerCycleInterval > 0) {159 new Thread(new Runnable() { // Thread safety reviewed160 @Override161 public void run() {162 boolean first = true;163 LOG.info("Starting auto registration thread. Will try to register every "164 + registerCycleInterval + " ms.");165 while (true) {166 try {167 boolean checkForPresence = true;168 if (first) {169 first = false;170 checkForPresence = false;171 }172 registerToHub(checkForPresence);173 } catch (GridException e) {174 LOG.info("Couldn't register this node: " + e.getMessage());175 }176 try {177 Thread.sleep(registerCycleInterval);178 } catch (InterruptedException e) {179 e.printStackTrace();180 }181 // While we wait for someone to rewrite server logging.182 LoggingManager.perSessionLogHandler().clearThreadTempLogs();183 }184 }185 }).start();186 } else {187 registerToHub(false);188 }189 }190 LoggingManager.perSessionLogHandler().clearThreadTempLogs();191 }192 public void setTimeout(int timeout, int cycle) {193 registrationRequest.getConfiguration().timeout = timeout;194 registrationRequest.getConfiguration().cleanUpCycle = cycle;195 }196 public void setMaxConcurrent(int max) {197 registrationRequest.getConfiguration().maxSession = max;198 }199 public GridNodeConfiguration getConfiguration() {200 return registrationRequest.getConfiguration();201 }202 /**203 * @return the {@link GridNodeServer} for this remote204 */205 protected GridNodeServer getServer() {206 return server;207 }208 /**209 * @return the list of {@link Servlet}s that this remote will bind210 */211 protected Map<String, Class<? extends Servlet>> getNodeServlets() {212 return nodeServlets;213 }214 private void registerToHub(boolean checkPresenceFirst) {215 if (!checkPresenceFirst || !isAlreadyRegistered(registrationRequest)) {216 String tmp =217 "http://" + registrationRequest.getConfiguration().getHubHost() + ":"218 + registrationRequest.getConfiguration().getHubPort() + "/grid/register";219 // browserTimeout and timeout are always fetched from the hub. Nodes don't have default values.220 // If a node has browserTimeout or timeout configured, those will have precedence over the hub.221 LOG.fine(222 "Fetching browserTimeout and timeout values from the hub before sending registration request");223 try {224 GridHubConfiguration hubConfiguration = getHubConfiguration();225 LOG.fine("Hub configuration: " + new Json().toJson(hubConfiguration));226 if (hubConfiguration.timeout == null || hubConfiguration.browserTimeout == null) {227 throw new GridException("Hub browserTimeout or timeout (or both) are null");228 }229 if (registrationRequest.getConfiguration().timeout == null) {230 registrationRequest.getConfiguration().timeout = hubConfiguration.timeout;231 timeoutFetchedFromHub = true;232 }233 if (registrationRequest.getConfiguration().browserTimeout == null) {234 registrationRequest.getConfiguration().browserTimeout = hubConfiguration.browserTimeout;235 browserTimeoutFetchedFromHub = true;236 }237 // The hub restarts and changes its configuration, the node fetches and updates its own again.238 // Only if it was previously fetched from the hub.239 if (timeoutFetchedFromHub) {240 registrationRequest.getConfiguration().timeout = hubConfiguration.timeout;241 }242 if (browserTimeoutFetchedFromHub) {243 registrationRequest.getConfiguration().browserTimeout = hubConfiguration.browserTimeout;244 }245 LOG.fine("Updated node configuration: " + new Json()246 .toJson(registrationRequest.getConfiguration()));247 } catch (Exception e) {248 LOG.warning(249 "Error getting the parameters from the hub. The node may end up with wrong timeouts." +250 e.getMessage());251 }252 try {253 URL registration = new URL(tmp);254 LOG.info("Registering the node to the hub: " + registration);255 HttpRequest request = new HttpRequest(POST, registration.toExternalForm());256 updateConfigWithRealPort();257 String json = new Json().toJson(registrationRequest);258 request.setContent(utf8String(json));259 HttpClient client = httpClientFactory.createClient(registration);260 HttpResponse response = client.execute(request);261 if (response.getStatus() != 200) {262 throw new GridException(String.format("The hub responded with %s", response.getStatus()));263 }264 LOG.info("The node is registered to the hub and ready to use");265 } catch (Exception e) {266 throw new GridException("Error sending the registration request: " + e.getMessage());267 }268 }269 }270 private void addExtraServlets(List<String> servlets) {271 if (servlets == null || servlets.size() == 0) {...

Full Screen

Full Screen

Source:Browser.java Github

copy

Full Screen

...61 public boolean is(String browserName) {62 return browserName().equals(browserName) || "Safari".equals(browserName);63 }64 };65 default String toJson() {66 return browserName();67 }68}...

Full Screen

Full Screen

toJson

Using AI Code Generation

copy

Full Screen

1import org.openqa.selenium.remote.InterfaceImplementation;2import org.openqa.selenium.remote.RemoteWebDriver;3import org.openqa.selenium.remote.http.HttpClient;4import org.openqa.selenium.remote.http.HttpResponse;5import org.openqa.selenium.remote.http.JsonHttpCommandCodec;6import org.openqa.selenium.remote.http.JsonHttpResponseCodec;7import org.openqa.selenium.remote.internal.WebElementToJsonConverter;8import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext;9import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextBuilder;10import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextBuilder.ElementContextBuilderImpl;11import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl;12import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder;13import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl;14import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.ElementContextImplBuilderImplImpl;15import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.ElementContextImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilder;16import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.ElementContextImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilder.ElementContextImplBuilderImplImplBuilderImpl;17import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.ElementContextImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilder.ElementContextImplBuilderImplImplBuilderImpl.ElementContextImplBuilderImplImplBuilderImplImpl;18import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.ElementContextImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilder.ElementContextImplBuilderImplImplBuilderImpl.ElementContextImplBuilderImplImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilderImplImplBuilder;19import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.ElementContextImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilder.ElementContextImplBuilderImplImplBuilderImpl.ElementContextImplBuilderImplImplBuilderImplImpl.ElementContextImplBuilderImplImplBuilderImplImplBuilder.ElementContextImplBuilderImplImplBuilderImplImplBuilderImpl;20import org.openqa.selenium.remote.internal.WebElementToJsonConverter.ElementContext.ElementContextImpl.ElementContextImplBuilder.ElementContextImplBuilderImpl.Element

Full Screen

Full Screen

toJson

Using AI Code Generation

copy

Full Screen

1import org.openqa.selenium.remote.InterfaceImplementation2import org.openqa.selenium.remote.InterfaceImplementation.*3import org.openqa.selenium.remote.InterfaceImplementation.Annotation.*4import org.openqa.selenium.remote.InterfaceImplementation.Method.*5import org.openqa.selenium.remote.InterfaceImplementation.Parameter.*6import org.openqa.selenium.remote.InterfaceImplementation.ReturnValue.*7InterfaceImplementation annotation = new InterfaceImplementation(8 methods = {9 @Method(10 parameters = {11 @Parameter(12 },13 returnValue = @ReturnValue(14 }15import org.openqa.selenium.remote.InterfaceImplementation16import org.openqa.selenium.remote.InterfaceImplementation.*17import org.openqa.selenium.remote.InterfaceImplementation.Annotation.*18import org.openqa.selenium.remote.InterfaceImplementation.Method.*19import org.openqa.selenium.remote.InterfaceImplementation.Parameter.*20import org.openqa.selenium.remote.InterfaceImplementation.ReturnValue.*21InterfaceImplementation annotation = new InterfaceImplementation(22 methods = {23 @Method(24 parameters = {25 @Parameter(26 },27 returnValue = @ReturnValue(28 }29import org.openqa.selenium.remote.InterfaceImplementation30import org.openqa.selenium.remote.InterfaceImplementation.*31import org.openqa.selenium.remote.InterfaceImplementation.Annotation.*32import org.openqa.selenium.remote.InterfaceImplementation.Method.*33import org.openqa.selenium.remote.InterfaceImplementation.Parameter.*34import org.openqa.selenium.remote.InterfaceImplementation.ReturnValue.*35InterfaceImplementation annotation = new InterfaceImplementation(36 methods = {37 @Method(38 parameters = {39 @Parameter(40 },41 returnValue = @ReturnValue(42 }43import org.openqa.selenium.remote.InterfaceImplementation44import org.openqa.selenium.remote.InterfaceImplementation.*45import org.openqa.selenium.remote.InterfaceImplementation.Annotation.*46import org.openqa.selenium.remote.InterfaceImplementation.Method.*47import org.openqa.selenium.remote.InterfaceImplementation.Parameter.*48import org

Full Screen

Full Screen

Selenium 4 Tutorial:

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.

Chapters:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

Selenium 101 certifications:

LambdaTest also provides certification for Selenium testing to accelerate your career in Selenium automation testing.

Run Selenium automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in Interface-Browser

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful