Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get browser version in local and container #215

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ buildscript {
masterThoughtVersion = '5.7.5'
browserStackLocalVersion = '1.1.0'
jetbrainsAnnotationsVersion = '24.0.1'
dockerJavaVersion = '3.2.9'
}
}

Expand Down Expand Up @@ -80,6 +81,7 @@ dependencies {
implementation "com.applitools:eyes-appium-java5:$project.applitoolsAppiumVersion"
implementation "com.applitools:eyes-selenium-java5:$project.applitoolsSeleniumVersion"
implementation "net.masterthought:cucumber-reporting:$masterThoughtVersion"
implementation "com.github.docker-java:docker-java:$dockerJavaVersion"
}

shadowJar {
Expand Down
1 change: 1 addition & 0 deletions configs/indigo_local_config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ LAUNCH_NAME_SUFFIX= on 'prod' Environment
TEST_DATA_FILE=./src/test/resources/testData.json
CLEANUP_DEVICE_BEFORE_STARTING_EXECUTION=false
BROWSER_CONFIG_FILE=./configs/browser_config.json
REMOTE_WEBDRIVER_GRID_PORT=GRID_PORT
171 changes: 164 additions & 7 deletions src/main/java/com/znsio/teswiz/runner/BrowserDriverManager.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package com.znsio.teswiz.runner;

import com.context.TestExecutionContext;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.ExecCreateCmdResponse;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.command.ExecStartResultCallback;
import com.znsio.teswiz.entities.Platform;
import com.znsio.teswiz.entities.TEST_CONTEXT;
import com.znsio.teswiz.exceptions.EnvironmentSetupException;
Expand All @@ -25,16 +32,19 @@
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariOptions;
import java.io.File;
import org.yaml.snakeyaml.Yaml;

Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
import java.io.*;
Copy link
Contributor

@snehith07 snehith07 Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the total imports from java.io > 4, if not you can import specific classes.
same for java.util

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

total imports from java.io are > 4

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.znsio.teswiz.runner.Runner.*;
import static com.znsio.teswiz.runner.Setup.CAPS;

Expand All @@ -47,6 +57,7 @@ class BrowserDriverManager {
private static final String MAXIMIZE = "maximize";
private static final String EXCLUDE_SWITCHES = "excludeSwitches";
private static final String SETTING_PROXY_FOR_BROWSER = "Setting Proxy for browser: ";
private static final String FETCH_CONTAINER_BROWSER_VERSION_COMMAND = "google-chrome-stable --version";
private static int numberOfWebDriversUsed = 0;
private static boolean shouldBrowserBeMaximized = false;
private static boolean isRunInHeadlessMode = false;
Expand Down Expand Up @@ -195,25 +206,171 @@ private static DriverManagerType setupBrowserDriver(TestExecutionContext testExe
String browserType) {
DriverManagerType driverManagerType = DriverManagerType.valueOf(browserType.toUpperCase());
String webDriverManagerProxyUrl = (null == Runner.getWebDriverManagerProxyURL()) ? ""
:
Runner.getWebDriverManagerProxyURL();
:
Runner.getWebDriverManagerProxyURL();
LOGGER.info(String.format(
"Using webDriverManagerProxyUrl: '%s' for getting the WebDriver for browser: '%s'",
webDriverManagerProxyUrl, browserType));

// TODO - get browser version from local or container. What about cloud?
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved

String localBrowserVersion = getLocalBrowserVersionFor(browserType);
String containerBrowserVersion = getContainerBrowserVersion();

WebDriverManager webDriverManager = WebDriverManager.getInstance(driverManagerType)
.proxy(webDriverManagerProxyUrl);
.proxy(webDriverManagerProxyUrl);
webDriverManager.setup();
String downloadedDriverVersion = webDriverManager.getDownloadedDriverVersion();

String message = String.format("Using %s browser version: %s", driverManagerType,
downloadedDriverVersion);
downloadedDriverVersion);
LOGGER.info(message);
ReportPortalLogger.logInfoMessage(message);
return driverManagerType;
}

private static String getContainerBrowserVersion() {
DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
DockerClient dockerClient = DockerClientBuilder.getInstance(config).build();

String imageName = "";
String containerId = "";

try {
Yaml yaml = new Yaml();
FileInputStream fis = new FileInputStream("docker-compose.yml");
Map<String, Object> data = yaml.load(fis);

Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
Map<String, Object> services = (Map<String, Object>) data.get("services");
Map<String, Object> selenium = (Map<String, Object>) services.get("chrome");
imageName = (String) selenium.get("image");
LOGGER.info("Selenium image: " + imageName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String.format() can be used to maintain uniformity

} catch (FileNotFoundException e) {
e.printStackTrace();
}

List<Container> containers = dockerClient.listContainersCmd()
.withShowAll(true)
.exec();
for (Container container : containers) {
if (container.getImage().equals(imageName)) {
containerId = container.getId();
}
}

assert containerId != null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the use of this assert here
and why are we passing it here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the container object does not find the matching id for container name it will return null. the assertion is added for the same.

ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(containerId)
.withCmd("sh", "-c", FETCH_CONTAINER_BROWSER_VERSION_COMMAND)
.withAttachStdout(true)
.withAttachStderr(true)
.exec();

String browserVersion = executeAndGetBrowserVersion(dockerClient, execCreateCmdResponse.getId());
LOGGER.info("Browser Version in container: " + browserVersion);
return browserVersion;
}

private static String executeAndGetBrowserVersion(DockerClient dockerClient, String execId) {
StringBuilder logOutput = new StringBuilder();
Pattern versionPattern = Pattern.compile("Google Chrome (\\d+\\.\\d+\\.\\d+\\.\\d+)");
try {
dockerClient.execStartCmd(execId)
.exec(new ExecStartResultCallback() {
@Override
public void onNext(Frame frame) {
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
logOutput.append(frame.toString());
}
}).awaitCompletion();
} catch (InterruptedException e) {
e.printStackTrace();
}
Matcher matcher = versionPattern.matcher(logOutput.toString());
if (matcher.find()) {
return matcher.group(1);
}
return null;
}

private static String getLocalBrowserVersionFor(String browserType) {
String binaryPath = "";
switch (browserType) {
case "chrome":
binaryPath = getChromeBinaryPath();
break;
case "firefox":
binaryPath = getFirefoxBinaryPath();
break;
case "safari":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are adding break in chrome, firefox, why not after safari

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to fetch the version of safari, we are executing a separate method getSafariVersion() and skipping the next steps in current method

return getSafariVersion();
default:
throw new InvalidTestDataException("Invalid browser : " + browserType);
}
ChromeOptions chromeOptions = new ChromeOptions();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required we have helper methods to get binary paths.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chrome options was used to set the binary path, removed and updated as we have helper methods to get the path

chromeOptions.setBinary(binaryPath);
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(binaryPath, "--version");
String version = "";
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
String[] split = line.split(" ");
version = split[split.length - 1];
LOGGER.info("Browser Version in system : " + version);
process.destroy();
} catch (IOException e) {
e.printStackTrace();
}
return version;
}

private static String getChromeBinaryPath() {
String os = System.getProperty("os.name").toLowerCase();
switch (os) {
case "win":
return System.getenv("ProgramFiles") + "\\Google\\Chrome\\Application\\chrome.exe";
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
case "mac os x":
return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
case "nix":
case "nux":
case "linux":
return "/usr/bin/google-chrome";
default:
throw new IllegalStateException("Unsupported operating system: " + os);
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
}
}

private static String getFirefoxBinaryPath() {
String os = System.getProperty("os.name").toLowerCase();
switch (os) {
case "win":
return System.getenv("ProgramFiles") + "\\Firefox\\Application\\firefox.exe";
case "mac":
return "/Applications/Firefox.app/Contents/MacOS/firefox";
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
case "nix":
case "nux":
case "linux":
return "/usr/bin/firefox";
default:
throw new IllegalStateException("Unsupported operating system: " + os);
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
}
}

private static String getSafariVersion() {
String safariVersion = "";
try {
Process process = Runtime.getRuntime()
.exec(new String[]{"defaults", "read", "/Applications/Safari.app/Contents/Info.plist", "CFBundleShortVersionString"});
Darshan3S marked this conversation as resolved.
Show resolved Hide resolved
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
safariVersion = reader.readLine();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
LOGGER.info("Safari version in system = " + safariVersion);
return safariVersion;
}

@NotNull
private static WebDriver createChromeDriver(String forUserPersona,
TestExecutionContext testExecutionContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Feature: Search for flight options

# CONFIG=./configs/indigo_local_config.properties PLATFORM=web TAG=searchFlights ./gradlew run
@web @searchFlights
@web @searchFlights @browserVersionTest
Scenario: Search for one way ticket from Pune to Delhi for single passenger
Given I search for a "one-way" ticket from "Pune" to "Delhi" for "1" adult passenger

Expand Down