-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,132 additions
and
2 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> | ||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" /> | ||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" /> | ||
<PackageReference Include="coverlet.collector" Version="3.2.0" /> | ||
<PackageReference Include="BrowserStackLocal" Version="2.3.1" /> | ||
<PackageReference Include="Appium.WebDriver" Version="4.4.5" /> | ||
<PackageReference Include="DotNetSeleniumExtras.WaitHelpers" Version="3.11.0" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Common\Common.csproj" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Remove="Config\" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Folder Include="Config\" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"platformName": "android", | ||
"appium:deviceName": "Google Pixel 3", | ||
"appium:osVersion": "9.0", | ||
"appium:app": "bs://<app_hashed_id>", | ||
"bstack:options": { | ||
"projectName": "BStack Demo", | ||
"buildName": "browserstack-build-1", | ||
"sessionName": "BStack local mstest", | ||
"userName": "BROWSERSTACK_USERNAME", | ||
"accessKey": "BROWSERSTACK_ACCESS_KEY", | ||
"debug": true, | ||
"local": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"commonCaps": { | ||
"platformName": "android", | ||
"appium:app": "bs://<app_hashed_id>", | ||
"bstack:options": { | ||
"projectName": "BStack Demo", | ||
"buildName": "browserstack-build-1", | ||
"userName": "BROWSERSTACK_USERNAME", | ||
"accessKey": "BROWSERSTACK_ACCESS_KEY", | ||
"debug": true | ||
} | ||
}, | ||
"pixel3": { | ||
"appium:deviceName": "Google Pixel 3", | ||
"appium:osVersion": "9.0", | ||
"bstack:options": { | ||
"sessionName": "BStack parallel mstest" | ||
} | ||
}, | ||
"samsungs10": { | ||
"appium:deviceName": "Samsung Galaxy S10", | ||
"appium:osVersion": "9.0", | ||
"bstack:options": { | ||
"sessionName": "BStack parallel mstest" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"platformName": "android", | ||
"appium:deviceName": "Google Pixel 3", | ||
"appium:osVersion": "9.0", | ||
"appium:app": "bs://<app_hashed_id>", | ||
"bstack:options": { | ||
"projectName": "BStack Demo", | ||
"buildName": "browserstack-build-1", | ||
"sessionName": "BStack single mstest", | ||
"userName": "BROWSERSTACK_USERNAME", | ||
"accessKey": "BROWSERSTACK_ACCESS_KEY", | ||
"debug": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using BrowserStack; | ||
using OpenQA.Selenium; | ||
using OpenQA.Selenium.Support.UI; | ||
using System.Collections.ObjectModel; | ||
|
||
namespace Android; | ||
|
||
[TestClass] | ||
public class LocalTest | ||
{ | ||
private AndroidDriver<AndroidElement>? driver; | ||
private string configFile = "LocalTest.json"; | ||
private Local? browserStackLocal; | ||
|
||
[TestInitialize] | ||
public void TestSetup() | ||
{ | ||
Utils utils = new Utils(null, "Config/" + configFile); | ||
AppiumOptions capabilities = utils.capabilities(); | ||
|
||
// Setup Browserstack Local | ||
browserStackLocal = new Local(); | ||
List<KeyValuePair<string, string>> bsLocalArgs = new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key", utils.accessKey()) }; | ||
browserStackLocal.start(bsLocalArgs); | ||
|
||
driver = new AndroidDriver<AndroidElement>(new Uri(Utils.HUB_URL), capabilities); | ||
} | ||
|
||
[TestMethod] | ||
public void LocalNetworkTest() | ||
{ | ||
if (driver == null) | ||
throw new Exception("Could not run tests. Driver not initialised"); | ||
|
||
var _ = driver.PageSource; | ||
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); | ||
|
||
var testActionId = By.Id("com.example.android.basicnetworking:id/test_action"); | ||
AndroidElement testActionElement = (AndroidElement)wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(testActionId)); | ||
testActionElement.Click(); | ||
Thread.Sleep(5000); | ||
|
||
_ = driver.PageSource; | ||
|
||
ReadOnlyCollection<AndroidElement> textviewElements = driver.FindElementsByClassName("android.widget.TextView"); | ||
string text = textviewElements.Last().Text; | ||
|
||
Assert.IsTrue(text.Contains("The active connection is wifi")); | ||
Assert.IsTrue(text.Contains("Up and running")); | ||
|
||
driver.ExecuteScript("browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"passed\", \"reason\": \"Test Passed!\"} }"); | ||
} | ||
|
||
[TestCleanup] | ||
public void TestTeardown() | ||
{ | ||
if (driver != null) | ||
driver.Quit(); | ||
|
||
if (browserStackLocal != null) | ||
browserStackLocal.stop(); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)] | ||
|
||
namespace Android; | ||
|
||
[TestClass] | ||
public class ParallelTest | ||
{ | ||
[TestMethod] | ||
[DataRow("samsungs10", "ParallelTest.json")] | ||
[DataRow("pixel3", "ParallelTest.json")] | ||
public void TestMethod1(string configName, string configFile) | ||
{ | ||
var singleTest = new SingleTest(configName, configFile); | ||
singleTest.TestSetup(); | ||
singleTest.SearchTest(); | ||
singleTest.TestTeardown(); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System.Collections.ObjectModel; | ||
using OpenQA.Selenium; | ||
using OpenQA.Selenium.Support.UI; | ||
|
||
namespace Android; | ||
|
||
[TestClass] | ||
public class SingleTest | ||
{ | ||
private AndroidDriver<AndroidElement>? driver; | ||
private string configFile = "SingleTest.json"; | ||
private string? configName; | ||
|
||
public SingleTest() { } | ||
|
||
public SingleTest(string _configName, string _configFile) | ||
{ | ||
configName = _configName; | ||
configFile = _configFile; | ||
} | ||
|
||
[TestInitialize] | ||
public void TestSetup() | ||
{ | ||
Utils utils = new Utils(configName, "Config/" + configFile); | ||
driver = new AndroidDriver<AndroidElement>(new Uri(Utils.HUB_URL), utils.capabilities()); | ||
} | ||
|
||
[TestMethod] | ||
public void SearchTest() | ||
{ | ||
if (driver == null) | ||
throw new Exception("Could not run tests. Driver not initialised"); | ||
|
||
var _ = driver.PageSource; | ||
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); | ||
|
||
var searchElementId = MobileBy.AccessibilityId("Search Wikipedia"); | ||
AndroidElement searchElement = (AndroidElement)wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(searchElementId)); | ||
searchElement.Click(); | ||
Thread.Sleep(2000); | ||
|
||
_ = driver.PageSource; | ||
|
||
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); | ||
var insertTextElementId = By.Id("org.wikipedia.alpha:id/search_src_text"); | ||
AndroidElement insertTextElement = (AndroidElement)wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(insertTextElementId)); | ||
insertTextElement.SendKeys("BrowserStack"); | ||
Thread.Sleep(5000); | ||
|
||
ReadOnlyCollection<AndroidElement> allProductsName = driver.FindElements(By.ClassName("android.widget.TextView")); | ||
Assert.IsTrue(allProductsName.Count > 0); | ||
|
||
driver.ExecuteScript("browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"passed\", \"reason\": \"Test Passed!\"} }"); | ||
} | ||
|
||
[TestCleanup] | ||
public void TestTeardown() | ||
{ | ||
if (driver != null) | ||
driver.Quit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
global using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
global using OpenQA.Selenium.Appium; | ||
global using OpenQA.Selenium.Appium.Android; | ||
global using Common; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||
<PackageReference Include="Appium.WebDriver" Version="4.4.5" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using System.Reflection; | ||
using Newtonsoft.Json.Linq; | ||
using OpenQA.Selenium.Appium; | ||
|
||
namespace Common; | ||
|
||
public class Utils | ||
{ | ||
public const string HUB_URL = "http://hub-cloud.browserstack.com/wd/hub"; | ||
public JObject testConfig; | ||
|
||
public Utils(string configName, string configPath) | ||
{ | ||
string? currentDirectory = GoUpLevels(Directory.GetCurrentDirectory(), 3); | ||
testConfig = JObject.Parse(File.ReadAllText(Path.Combine(currentDirectory, configPath))); | ||
|
||
// ConfigName is present for parallel test configs. | ||
if (configName is not null) | ||
{ | ||
JObject targetConfig = (JObject)testConfig.GetValue(configName); | ||
if (targetConfig is null) | ||
throw new Exception("Config Name used for invoking parallel test is not valid"); | ||
|
||
testConfig = (JObject)testConfig.GetValue("commonCaps"); | ||
testConfig.Merge(targetConfig); | ||
} | ||
|
||
if (testConfig is null) | ||
throw new Exception("Could not parse config from the config json file"); | ||
} | ||
|
||
public AppiumOptions capabilities() | ||
{ | ||
AppiumOptions capabilities = new AppiumOptions(); | ||
Dictionary<string, object> browserstackOptions = new Dictionary<string, object>(); | ||
|
||
// Parse all keys at root level and build AppiumOptions out of it. | ||
foreach (var property in testConfig.Properties()) | ||
{ | ||
if (property.Value.Type != JTokenType.Object) | ||
capabilities.AddAdditionalCapability(property.Name, (JValue)property.Value); | ||
} | ||
// Update bstack:options with user creds. value in config file takes precedence over env variable. | ||
if (!testConfig.ContainsKey("bstack:options")) | ||
testConfig.Add("bstack:options", new JObject()); | ||
|
||
testConfig["bstack:options"]["userName"] = username(); | ||
testConfig["bstack:options"]["accessKey"] = accessKey(); | ||
|
||
// Parse nested bstack:options and push into AppiumOptions | ||
JObject bStackOptions = (JObject)testConfig["bstack:options"]; | ||
foreach (var property in bStackOptions.Properties()) | ||
{ | ||
if (property.Value.Type != JTokenType.Object) | ||
browserstackOptions.Add(property.Name, (JValue)property.Value); | ||
} | ||
|
||
capabilities.AddAdditionalCapability("bstack:options", browserstackOptions); | ||
|
||
return capabilities; | ||
} | ||
|
||
private string? username() | ||
{ | ||
string? username = (string?)testConfig["bstack:options"]["userName"]; | ||
if (username is null) | ||
username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME_OLD"); | ||
|
||
return username; | ||
} | ||
|
||
public string? accessKey() | ||
{ | ||
string? accessKey = (string?)testConfig["bstack:options"]["accessKey"]; | ||
if (accessKey is null) | ||
accessKey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY_OLD"); | ||
|
||
return accessKey; | ||
} | ||
|
||
private static string GoUpLevels(string path, int levels) | ||
{ | ||
// Combine with ".." for each level to go up | ||
string newPath = path; | ||
for (int i = 0; i < levels; i++) | ||
{ | ||
newPath = Path.Combine(newPath, ".."); | ||
} | ||
|
||
// Get the full path after going up the specified levels | ||
return Path.GetFullPath(newPath); | ||
} | ||
} | ||
|
Oops, something went wrong.