diff --git a/Android/README.md b/Android/README.md index 1e87943..23a7f56 100644 --- a/Android/README.md +++ b/Android/README.md @@ -1,6 +1,6 @@ TestProject C\# SDK - Android Examples ====================================== -Tests & Addons examples. +Tests examples. You can find all information on how to use TestProject SDK in the [root of this repository](https://github.com/testproject-io/csharp-sdk-examples). \ No newline at end of file diff --git a/Generic/README.md b/Generic/README.md deleted file mode 100644 index 966e3dc..0000000 --- a/Generic/README.md +++ /dev/null @@ -1,6 +0,0 @@ -TestProject C\# SDK - Generic Examples -====================================== - -Tests & Addons examples. - -You can find all information on how to use TestProject SDK in the [root of this repository](https://github.com/testproject-io/csharp-sdk-examples). \ No newline at end of file diff --git a/IOS/README.md b/IOS/README.md index f057bc9..27eca80 100644 --- a/IOS/README.md +++ b/IOS/README.md @@ -1,6 +1,6 @@ TestProject C\# SDK - iOS Examples ====================================== -Tests & Addons examples. +Tests examples. You can find all information on how to use TestProject SDK in the [root of this repository](https://github.com/testproject-io/csharp-sdk-examples). \ No newline at end of file diff --git a/README.md b/README.md index 30f11cf..6b132c2 100644 --- a/README.md +++ b/README.md @@ -1,355 +1,316 @@ -# TestProject C# SDK +# TestProject SDK for C# -This repository contains code examples based on TestProject C# SDK. +[TestProject](https://testproject.io/) is a Free Test Automation platform for Web and Mobile. \ +To get familiar with the TestProject, visit our main [documentation](https://docs.testproject.io/) website. -## Briefing +TestProject SDK is a single, integrated interface to scripting with the most popular open source test automation frameworks. -This document describes the bare minimum steps to start developing tests using the C# .Net Core SDK.\ -TestProject provides a unified test automation SDK with support for Android, iOS and Web applications by utilizing the open-source Selenium and Appium frameworks. -TestProject is OS agnostic and can run on Windows, Linux or Mac. -It is a full stack automation framework with capabilities that allow automation test management, remote and local test execution, job scheduling, reporting dashboards, collaboration and more. -TestProject's C# SDK adds several features not present in .Net Core such as Page Object support via PageFactory. +From now on, you can effortlessly execute Selenium and Appium native tests using a single automation platform that already takes care of all the complex setup, maintenance and configs. -## Minimum Requirements +With one unified SDK available across multiple languages, developers and testers receive a go-to toolset, solving some of the greatest challenges in open source test automation. -* In order to develop TestProject C# tests/addons, you must have .Net Core SDK version v2.1 or greater (Can be downloaded [here](https://dotnet.microsoft.com/download/dotnet-core/2.1)) -* In order to execute C# tests/addons, you must have .Net Runtime v2.1 or greater (Can be downloaded [here](https://dotnet.microsoft.com/download/dotnet-core/2.1)) -* If you are developing with visual studio, you must use Visual Studio 2017 (Can be downloaded [here](https://visualstudio.microsoft.com/downloads/)) +With TestProject SDK, users save a bunch of time and enjoy the following benefits out of the box: -## Preparations +* Available as a [NuGet](https://www.nuget.org/packages/TestProject.SDK) package. +* 5-mins simple Selenium and Appium setup with a single [Agent](https://docs.testproject.io/testproject-agents) deployment. +* Automatic test reports in HTML/PDF format (including screenshots). +* Collaborative reporting dashboards with execution history and RESTful API support. +* Always up-to-date with the latest and stable Selenium driver version. +* A simplified, familiar syntax for both web and mobile applications. +* Complete test runner capabilities for both local and remote executions, anywhere. +* Cross platform support for Mac, Windows, Linux and Docker. +* Ability to store and execute tests locally on any source control tool, such as Git. -To kick-off automation development with TestProject, it is necessary to have an active TestProject account and the TestProject Agent installed.\ -TestProject's Agent is a cross-platform desktop application, allowing you to create, debug and execute your test automation locally. -TestProject Agent can be downloaded from [Agents](https://app.testproject.io/#/agents) page. +# Getting Started -### Getting C# SDK +To get started, you need to complete the following prerequisites checklist: -You can download TestProject SDK for C# from the [Developers](https://app.testproject.io/#/developers) page and reference it in your project. +* Login to your account at https://app.testproject.io/ or [register](https://app.testproject.io/signup/) a new one. +* [Download](https://app.testproject.io/#/download) and install an Agent for your operating system or pull a container from [Docker Hub](https://hub.docker.com/r/testproject/agent). +* Run the Agent and [register](https://docs.testproject.io/getting-started/installation-and-setup#register-the-agent) it with your Account. +* Get a development token from [Integrations / SDK](https://app.testproject.io/#/integrations/sdk) page. +* Have [.NET Core SDK 2.1](https://dotnet.microsoft.com/download/dotnet-core/2.1) installed on your machine. +* Have a [Visual Studio](https://visualstudio.microsoft.com/downloads/) IDE installed. -## Test Development +## Installation -The best way to start developing automated tests with TestProject is by reviewing the source code of a basic test that performs a login and updates a profile form, expecting the save to succeed.\ -* [Web](Web/Test/TestProject.SDK.Examples.Web.Test/Test/BasicTest.cs) test executed on [TestProject Demo](https://example.testproject.io/web/index.html) website. -* [Android](Android/Test/TestProject.SDK.Examples.Android.Test/Test/BasicTest.cs) test executed on [TestProject Demo](https://github.com/testproject-io/android-demo-app) App for Android. -* [iOS](IOS/Test/Test/BasicTest.cs) test executed on [TestProject Demo](https://github.com/testproject-io/ios-demo-app) App for iOS. - -There is also a [Generic](Generic/Test/TestProject.SDK.Examples.Generic.Test/Test/BasicTest.cs) test, representing a dummy scenario that can be automated.\ -It can be used as a reference for real scenarios that automate a non-UI sequences (those that do not require a Selenium or Appium driver). - -### Build your first C# Project -To begin, let's create a .Net Core project and add TestProject SDK as a reference: -* Open Visual studio and create a new project -* From the left side select ```Visual C# => .Net Core```. Then, select ```Class Library``` -* Once the project has been created, right-click the project and select ```Manage Nuget Packages...```. -* Search for ```TestProject SDK``` and install it in your project. -* Right click your project file and press ```Edit Project File``` -* Find the `````` tag containing TestProject SDK and add to it the ```Publish="false"``` property. This is required to package your final code for uploading to TestProject website. - -There we go, now we're all set! Let's see what - -### Test Class - -In order to build a Test that can be executed by TestProject, the class has to implement on of the interfaces that the SDK provides.\ -Interface implementation requires an implementation of the *Execute()* method, that will be be invoked by the platform to run the Test.\ -The *Execute()* method returns *ExecutionResult* enum which can be **PASSED** or **FAILED**. - -Below are some examples for Test implementation on different platforms: - -
Web Test -

- -BasicTest class implements the *IWebTest* interface: - -```csharp -public class BasicTest : IWebTest -``` +TestProject SDK for C# is available via [NuGet](https://www.nuget.org/packages/TestProject.SDK). -Test entry point is the *Execute* method: +* Right-click the project and select `Manage NuGet Packages...` +* Search for `TestProject SDK` and add it to your project. -```csharp -public ExecutionResult Execute(WebTestHelper helper) -``` +# Test Development -The following line of code retrieves a driver to automate the browser. +A test class has to implement **one** of the following interfaces: -```csharp -// Get driver initialized by TestProject Agent -// No need to specify browser type, it can be done later via UI -var driver = helper.Driver; -``` - -Following code is used to navigate the browser to the relevant URL. -After it is executed, TestProject Demo page is loaded. - -```csharp -// Navigate to TestProject Demo website -driver.Navigate().GoToUrl("https://example.testproject.io/web/"); +```ascii +TestProject.SDK.Tests +├── IWebTest +├── IAndroidTest +└── IIOSTest ``` -The following code uses the Page Object Model pattern to login in and complete a profile form, saving it: +Here is an example of creating & running a test class implementing the `IWebTest` interface. \ +This test performs a login and expects a logout button to appear: ```csharp -// Initialize the properties of the LoginPage with the driver -var loginPage = new LoginPage(); -PageFactory.InitElements(driver, loginPage); - -// Login using provided credentials -loginPage.Login(name, password); - -// Initialize the properties of the profilePage with the driver -var profilePage = new ProfilePage(); -PageFactory.InitElements(driver, profilePage); - -// Complete profile forms and save it -profilePage.UpdateProfile(country, address, email, phone); -``` - -The following return statement will assert test result: +using OpenQA.Selenium; +using TestProject.Common.Attributes; +using TestProject.Common.Enums; +using TestProject.SDK; +using TestProject.SDK.Tests; +using TestProject.SDK.Tests.Helpers; -```csharp -return profilePage.Saved ? ExecutionResult.Passed : ExecutionResult.Failed; +namespace MyFirstExample +{ + public class Program + { + static void Main(string[] args) + { + using (Runner runner = new RunnerBuilder("YOUR-DEV-TOKEN") + .AsWeb(AutomatedBrowserType.Chrome).Build()) + { + runner.Run(new BasicTest()); + } + } + + [Test(Name="Basic Test")] + class BasicTest : IWebTest + { + public ExecutionResult Execute(WebTestHelper helper) + { + // Get driver initialized by TestProject Agent + // No need to specify browser type, it can be done later via UI + var driver = helper.Driver; + + driver.Navigate().GoToUrl("https://example.testproject.io/web/"); + + driver.FindElementByCssSelector("#name").SendKeys("John Smith"); + driver.FindElementByCssSelector("#password").SendKeys("12345"); + driver.FindElementByCssSelector("#login").Click(); + + if (driver.FindElements(By.CssSelector("#logout")).Count > 0) + return ExecutionResult.Passed; + return ExecutionResult.Failed; + } + } + } +} ``` -

-
- -
Android Test -

+Below are links to other examples with complete source code: -BasicTest class implements the *IAndroidTest* interface: +* [Web](Web/Test/TestProject.SDK.Examples.Web.Test/Test/BasicTest.cs) test executed on [TestProject Demo](https://example.testproject.io/web/index.html) website. +* [Android](Android/Test/TestProject.SDK.Examples.Android.Test/Test/BasicTest.cs) test executed on [TestProject Demo](https://github.com/testproject-io/android-demo-app) App for Android. +* [iOS](IOS/Test/Test/BasicTest.cs) test executed on [TestProject Demo](https://github.com/testproject-io/ios-demo-app) App for iOS. -```csharp -public class BasicTest : IAndroidTest -``` +## Test Running -Test entry point is the *Execute* method: +To debug or run the test, you will have to use the **Runner** class. \ +Here' is an `NUnit` example that executes the `BasicTest` shown above: ```csharp -public ExecutionResult Execute(AndroidTestHelper helper) -``` - -The following line of code retrieves a driver to automate the App. +using NUnit.Framework; +using TestProject.Common.Enums; +using TestProject.SDK.Examples.Web.Runners.Nunit.Base; -```csharp -// Get driver initialized by TestProject Agent -var driver = helper.Driver; +namespace TestProject.SDK.Examples.Runners.Nunit +{ + public class BasicTests + { + Runner runner; + + [OneTimeSetUp] + public void SetUp() + { + runner = new RunnerBuilder(DevToken).AsWeb(AutomatedBrowserType.Chrome).Build(); + } + + [Test] + public void TestLogin() + { + runner.Run(new BasicTest()); + } + + [OneTimeTearDown] + public void TearDown() + { + runner.Dispose(); + } + } +} ``` -The following code resets the App and uses the Page Object Model pattern to login in and complete a profile form, saving it: +Below are examples for initialization of other Runner types: +**Desktop Web** ```csharp -driver.ResetApp(); - -// Login using provided credentials -var loginPage = new LoginPage(driver); -PageFactory.InitElements(driver, loginPage); - -// Perform login -loginPage.Login(name, password); - -// Complete profile form -var profilePage = new ProfilePage(driver); -PageFactory.InitElements(driver, profilePage); - -profilePage.UpdateProfile(country, address, email, phone); +var runner = new RunnerBuilder("DEV_TOKEN") + .AsWeb(AutomatedBrowserType...).Build(); ``` -The following return statement will assert test result: +**Android** ```csharp -return profilePage.Saved ? ExecutionResult.Passed : ExecutionResult.Failed; +var runner = new RunnerBuilder("DEV_TOKEN") + .AsAndroid("DEVICE_UDID", "APP_PACKAGE", "ACTIVITY").Build(); ``` -

-
- -
iOS Test -

- -BasicTest class implements the *IIOSTest* interface: +**Chrome on Android** ```csharp -public class BasicTest : IIOSTest +var runner = new RunnerBuilder("DEV_TOKEN") + .AsAndroidWeb("DEVICE_UDID").Build(); ``` -Test entry point is the *Execute* method: +**iOS** ```csharp -public ExecutionResult Execute(IOSTestHelper helper) +var runner = new RunnerBuilder("DEV_TOKEN") + .AsIOS("DEVICE_UDID", "DEVICE_NAME", "APP_BUNDLE_ID").Build(); ``` -The following line of code retrieves a driver to automate the App. +**Safari on iOS** ```csharp -// Get driver initialized by TestProject Agent -var driver = helper.Driver; +var runner = new RunnerBuilder("DEV_TOKEN") + .AsIOSWeb("IOS_DEVICE_ID", "IOS_DEVICE_NAME").Build(); ``` -The following code resets the App and uses the Page Object Model pattern to login in and complete a profile form, saving it: - -```csharp -driver.ResetApp(); - -// Login using provided credentials -var loginPage = new LoginPage(driver); -PageFactory.InitElements(driver, loginPage); +## Reports -// Perform login -loginPage.Login(name, password); - -// Complete profile form -var profilePage = new ProfilePage(driver); -PageFactory.InitElements(driver, profilePage); - -profilePage.UpdateProfile(country, address, email, phone); -``` +TestProject SDK reports all driver commands and their results to the TestProject Cloud. \ +Doing so, allows us to present beautifully designed reports and statistics in our dashboards. -The following return statement will assert test result: +Reports can be completely disabled via `RunnerBuilder`, for example: ```csharp -return profilePage.Saved ? ExecutionResult.Passed : ExecutionResult.Failed; +var runner = new RunnerBuilder("DEV_TOKEN") + .WithReportsDisabled() + .AsWeb(AutomatedBrowserType...) + .Build(); ``` -

-
+There are more options to disable reporting of specific entities. \ +See [Disabling Reports](#disabling-reports) section for more information. -
Generic Test -

+## Implicit Project and Job Names -BasicTest class implements the *IGenericTest* interface: +The SDK will attempt to infer Project and Job names from NUnit / MSTest / XUnit attributes. \ +If found, the following logic and priorities take place: -```csharp -public class BasicTest : IGenericTest -``` +* _Namespace_ of the class where the `Runner` is created, is used for **Project** name. +* _Class_ name where the `Runner` is created, is used for the **Job** name. +* _Test class_ name, or the _Name_ property of the `Test` attribute on the class is used for the **Test** name. + +Examples of implicit Project & Job names inferred from annotations: +* [NUnit example](Web/Test/TestProject.SDK.Examples.Web.Test/Runners/Nunit/DesktopTests.cs) +* [Console Program example](Web/Test/TestProject.SDK.Examples.Web.Test/Runners/Console/Program.cs) -Test entry point is the *execute* method: +## Explicit Names -```csharp -public ExecutionResult Execute(GenericTestHelper helper) -``` - -The following code adds the value stored in 'a' variable to the value in 'b' and if equals 2, asserts success: +Project and Job names can be also specified explicitly using the relevant options in `RunnerBuilder`, for example: ```csharp -int a = 1, b = 1; - -if (a + b == 2) - return ExecutionResult.Passed; -else - return ExecutionResult.Failed; - +var runner = new RunnerBuilder("DEV_TOKEN") + .WithProjectName("My First Project") + .WithJobName("My First Job") + .AsWeb(AutomatedBrowserType...) + .Build(); ``` -

-
+You can specify a Project, a Job name or both. If you don't, the value will be inferred automatically. \ +See [Implicit Project and Job Names](#implicit-project-and-job-names) section for more information on how these names are inferred. -### Debugging / Running Test +Examples of explicit Project & Job names configuration: +* [NUnit example](Web/Test/TestProject.SDK.Examples.Web.Test/Runners/Nunit/ExplicitNameTests.cs) +## Tests Reports -To debug or run the test locally, you will have to use the *Runner* class from TestProject SDK. -All code examples, have NUnit tests that use *Runner* to debug the automation locally. -Debugging or running a test locally with the *Runner* class, requires authentication before communication with the TestProject Agent (since it is the execution engine). -Development token for authentication can be easily obtained from the [Developers](https://app.testproject.io/#/developers) page. -It should be used as a parameter in one of the *Runner* factory methods: +### Tests Reporting -
Web -

+Tests are reported automatically when a test **ends**, in other works, when `Runner.Run()` method execution ends.\ +Test names are inferred from the `[Test]` attribute's _Name_ property if it is present, or from the test class name. -```csharp -var runner = RunnerFactory.Instance.CreateWeb("YOUR_DEV_TOKEN", AutomatedBrowserType.Chrome) // Use the BrowserName you need -``` +> This behavior can't be overridden or disabled at this time. -

-
+Each call to `Runner.Run` will create a separate test in a job report. \ +Even calls in the same testing framework method behave this way. -
Android -

+For example, following NUnit based code, will generate the following _four_ tests in the report: ```csharp -var runner = RunnerFactory.Instance.CreateAndroid("YOUR_DEV_TOKEN", "YOUR_EMULATOR_ID", "YOUR_APP_PACKAGE", "YOUR_ACTIVITY") -``` - -

-
-
Chrome on Android -

- -```csharp -var runner = RunnerFactory.Instance.CreateAndroidWeb("YOUR_DEV_TOKEN", "YOUR_EMULATOR_ID", BrowserName.Chrome) // Use the BrowserName you need -``` + class Test : IWebTest + { + [Parameter] + public string url; -

-
+ public ExecutionResult Execute(WebTestHelper helper) + { + helper.Driver.Navigate().GoToUrl(url); + return ExecutionResult.Passed; + } + } -
iOS -

+ public DesktopTests(AutomatedBrowserType automatedBrowserType) + { + runner = new RunnerBuilder("DevToken") + .AsWeb(AutomatedBrowserType.Chrome).Build(); + } -```csharp -var runner = RunnerFactory.Instance.CreateIOS("YOUR_DEV_TOKEN", "YOUR_IOS_DEVICE_ID", "YOUR_IOS_DEVICE_NAME", "YOUR_IOS_APP") -``` + [Test] + public void RunGoogle() + { + var test = new Test() { url = "http://www.google.com" }; + runner.Run(test); + } -

-
+ [Test] + public void RunTestProject() + { + var test = new Test() { url = "http://testproject.io" }; + runner.Run(test); + } -
Safari on iOS -

+ [Test] + public void RunAll() + { + var test = new Test() { url = "http://www.google.com" }; + runner.Run(test); + test = new Test() { url = "http://testproject.io" }; + runner.Run(test); + } -```csharp -var runner = RunnerFactory.Instance.CreateIOSWeb("YOUR_DEV_TOKEN", "YOUR_IOS_DEVICE_ID", "YOUR_IOS_DEVICE_NAME") + [OneTimeTearDown] + public void TearDown() + { + runner.Dispose(); + } ``` -

-
- -
Generic -

+Report: -```csharp -var runner = RunnerFactory.Instance.Create("YOUR_DEV_TOKEN") +```ascii +Report +├── RunGoogle +│ └── Navigate To https://google.com/ +├── RunTestProject +│ └── Navigate To http://testproject.io +└── RunAll + ├── Navigate To https://google.com/ + └── Navigate To http://testproject.io ``` -

-
- -### Using parameters and step reports in your tests - -Let's make our example more advanced by adding parameters. To add parameters to your test, you simply need to add fields with relevant attributes.\ -In addition, we will create step reports to separate the different stages of the test (each report will appear as a separate step in the future execution reports). +### Steps -See the relevant platform link for full source code: +Steps are reported automatically when driver commands are executed. \ +Even if this feature is disabled, or in addition, steps can still be reported **manually** -* [Web - Extended Test](Web/Test/TestProject.SDK.Examples.Web.Test/Test//ExtendedTest.cs) -* [Android - Extended Test](Android/Test/TestProject.SDK.Examples.Android.Test/Test//ExtendedTest.cs) -* [iOS - Extended Test](IOS/Test/Test/ExtendedTest.cs) -* [Generic - Extended Test](Generic/Test/TestProject.SDK.Examples.Generic.Test/Test/ExtendedTest.cs) - -#### Test Attributes - -TestProject SDK provides attributes to describe the test and its parameters: - - 1. The ***Test*** attribute is used to better describe the Test and define how it will appear later in TestProject UI: - * **Name** - The name of the test (if omitted, the name of the class will be used). - * **Description** - A short description of the test which is shown in various places in TestProject platform (e.g. reporting dashboard). The description may contain placeholders {{propertyName}} that will be changed dynamically according to test parameters. - * **Version** - A version string which is used for future reference. - 1. The ***Parameter*** attribute is used to better describe your Test inputs and outputs, in the example above there are two inputs - *url* and *expectedTitle*. - * **Description** - The description of the parameter - * **Direction** - Defines the parameter as an *Input* (default if omitted) or an *Output* parameter. An *Input* parameter will receive values when the test is executed while the *Output* parameter value will be retrieved at the end of test execution (and can be used in following steps later on in the automation scenario). - * **DefaultValue** - Defines a default value that will be used for the parameter. - -#### Reports - -Implemented *Execute()* method receives a _Helper_ instance as a parameter.\ -Via this helper, you can obtain an instance of _TestReporter_ class. - -```csharp -var report = helper.Reporter; -``` - -Notice the following line in the Extended Test example.\ +Notice the following line in the [Extended Test](Web/Test/TestProject.SDK.Examples.Web.Test/Test/ExtendedTest.cs) example. \ This line reports a step based on provided condition and takes a screenshot: ```csharp -report.Step("Profile information saved", profilePage.Saved, TakeScreenshotConditionType.Always); +helper.Reporter.Step("Profile information saved", profilePage.Saved, TakeScreenshotConditionType.Always); ``` Using the following code one can set test result message: @@ -358,372 +319,32 @@ Using the following code one can set test result message: report.Result = "Test completed successfully"; ``` -## Addon development - -Much like Tests you can develop custom Addons to extend TestProject and shape your automated testing solution for your needs.\ -An Addon is a set of Actions (one or more) where each Action does a specific task, a common Addon scenario will be to extend basic set of Actions on complicated UI elements or make wrappers for user defined API.\ -Once created, Actions can be used to design steps of automated tests. - -### Addon Manifest - -To start developing an Addon a manifest file is required. The manifest is a descriptor of your Addon, it contains a unique GUID for the addon and a list of required permissions.\ -Create an Addon in the [Addons](https://app.testproject.io/#/addons/account) screen and download the generated manifest. Then, add the manifest to your package as follows: -* If your addon consists of a single file (e.g. has no dependencies), add the manifest to your project root folder. Then, mark it as an embedded resource by opening the *Properties* panel and change *Build Action* to *Embedded Resource*. -* If your addon consists of multiple files (e.g. has dependencies), add the manifest to the .zip file that you are going to upload to TestProject. - -### Implement the Addon - -Lets review a simple Addon with a **ClearFields** action that clears a form. -It can be used on the login form in TestProject Demo website or mobile App: - -* [Web - Action](Web/Addon/TestProject.SDK.Examples.Web.Addon/Addon/ClearFieldsAction.cs) -* [Android - Action](Android/Addon/TestProject.SDK.Examples.Android.Addon/Addon/ClearFieldsAction.cs) -* [iOS - Action](IOS/Addon/TestProject.SDK.Examples.IOS.Addon/Addon/ClearFieldsAction.cs) - -There is also a [Generic](Generic/Addon/TestProject.SDK.Examples.Generic.Addon/Addon/AdditionAction.cs) action, representing a dummy scenario that can be automated.\ -It can be used as a reference for real scenarios that automate a non-UI (those hat do not require a Selenium or Appium driver) actions. - -#### Action Class - -In order to build an Action that can be executed by TestProject, the class has to implement one of the interfaces that the SDK provides.\ -Action class can also be decorated with the *[Action]* attribute to provide extra information about the action. - -Interface implementation requires an implementation of the *Execute()* method, that will be be invoked by the platform to run the Action.\ -The *Execute()* method returns *ExecutionResult* enum which can be **PASSED** or **FAILED**. - -
Web Action -

- -```csharp -[Action(Name = "Clear Fields")] -public class ClearFieldsAction : IWebAction -``` - -Action entry point is the *Execute* method: - -```csharp -public ExecutionResult Execute(WebAddonHelper helper) -``` - -Action code searches for visible Forms and then for contained inputs elements, clearing them one by one: - -```csharp -// Get Driver -var driver = helper.Driver; - -// Search for Form elements -foreach (IWebElement form in driver.FindElements(By.TagName("form"))) -{ - // Ignore invisible forms - if (!form.Displayed) - continue; - - // Clear all inputs - foreach (IWebElement element in form.FindElements(By.TagName("input"))) - element.Clear(); -} - -return ExecutionResult.Passed; -``` - -

-
- -
Android Action -

- -```csharp -[Action(Name = "Clear Fields")] -public class ClearFieldsAction : IAndroidAction -``` - -Action entry point is the *Execute* method: +## Disabling Reports -```csharp -public ExecutionResult Execute(AndroidAddonHelper helper) -``` - -Action code searches for EditText elements, clearing them one by one: - -```csharp -foreach (AndroidElement element in helper.Driver.FindElements(By.ClassName("android.widget.EditText"))) - element.Clear(); -``` - -

-
- -
iOS Action -

- -```csharp -@Action(name = "Clear Fields") -public class ClearFields : IIOSAction -``` - -Action entry point is the *Execute* method: - -```csharp -public ExecutionResult Execute(IOSAddonHelper helper) -``` - -Action code searches for XCUIElementTypeTextField and XCUIElementTypeSecureTextField elements, clearing them one by one: - -```csharp -for (var element in helper.Driver.findElements(By.className("XCUIElementTypeTextField"))) - element.clear(); - -for (IOSElement element : helper.Driver.findElements(By.className("XCUIElementTypeSecureTextField"))) - element.clear(); -``` - -

-
- -
Generic Action -

- -```csharp -[Action(Name = "Addition", Description = "Add {{a}} to {{b}}")] -public class AdditionAction : IGenericAction -``` - -Action entry point is the *Execute* method: - -```csharp -public ExecutionResult Execute(GenericAddonHelper helper) -``` - -Action code performs an addition of values in two variables, assigning result to third: - -```csharp -result = a + b; -``` - -

-
- - -Actions run in context of a test and assume that required UI state is already in place.\ -When the action will be used in a test it will be represented as a single step, usually preceded by other steps.\ -However, when debugging it locally, preparations should be done using the *Runner* class to start from expected UI state: - -
Web - State Preparation -

- -```csharp -// Create Action -ClearFields action = new ClearFields(); - -// Prepare state -var driver = (WebDriver)runner.GetDriver(); -driver.Navigate().GoToUrl("https://example.testproject.io/web/"); -driver.FindElement(By.Id("name")).SendKeys("John Smith"); -driver.FindElement(By.Id("password")).SendKeys("12345"); - -// Run action -runner.Run(action); -``` - -

-
- -
Android - State Preparation -

- -```csharp -// Create Action -var action = new ClearFields(); - -// Prepare state -var driver = (AndroidDriver)runner.GetDriver(); -driver.FindElement(By.Id("name")).SendKeys("John Smith"); -driver.FindElement(By.Id("password")).SendKeys("12345"); - -// Run action -runner.Run(action); -``` - -

-
- -
iOS - State Preparation -

- -```csharp -// Create Action -var action = new ClearFields(); - -// Prepare state -var driver = (IOSDriver)runner.GetDriver(); -driver.FindElement(By.Id("name")).SendKeys("John Smith"); -driver.FindElement(By.Id("password")).SendKeys("12345"); - -// Run action -runner.Run(action); -``` +Reporting can be disabled during Runner creation.\ +If reporting was explicitly disabled when the runner was created, it can **not** be enabled later. -

-
+### Disable all reports -#### Action Attributes - -TestProject SDK provides attributes to describe the action: - - 1. The ***Action*** attribute is used to better describe your action and define how it will appear later in TestProject UI: - * **Name** - The name of the action (if omitted, the name of the class will be used). - * **Description** - A description of the test which is shown in various places in TestProject platform (reports for example). The description can use placeholders {{propertyName}} do dynamically change the text according to test properties. - * **Version** - A version string which is used for future reference. - 1. The ***Parameter*** attribute is used to better describe your action's inputs and outputs, in the example above there are two parameters - *question* and *answer*. - * **Description** - The description of the parameter - * **Direction** - Defines the parameter as an *input* (default if omitted) or an *output* parameter. An *input* parameter will able to receive values when it is being executed while the *output* parameter value will be retrieved at the end of test execution (and can be used in other places later on in the automation scenario). - * **DefaultValue** - Defines a default value that will be used for the parameter. - -> NOTE: Unlike tests, actions cannot use assertions because an action is a single generic reusable unit. - -### Debugging / Running Actions - -To debug or run the action locally, you will have to use the *Runner* class from TestProject SDK. -All code examples, have NUnit tests that use *Runner* to debug the automation locally. - -### Element Actions - -Actions can be element based, when their scope is limited to operations on a specific element and not the whole DOM.\ -This allows creating smart crowd based addons for industry common elements and libraries. - -*TypeRandomPhone* is an example of an Element Action: - -* [Web - Element Action](Web/Addon/TestProject.SDK.Examples.Web.Addon/Addon/TypeRandomPhoneAction.cs) -* [Android - Element Action](Android/Addon/TestProject.SDK.Examples.Android.Addon/Addon/TypeRandomPhoneAction.cs) -* [iOS - Element Action](IOS/Addon/TestProject.SDK.Examples.IOS.Addon/Addon/TypeRandomPhoneAction.cs) - -This action generates a random phone number based on provided country code and max digits amount, typing it in a text field: - -```csharp -var randomer = new Random(); -long number = randomer.Next(1, (int)Math.Pow(10, maxDigits)); -phone = $"+{countryCode}{number}"; -element.SendKeys(phone); -return ExecutionResult.Passed; -``` - -It also stores the result in an output field (see the attribute and ***ParameterDirection.OUTPUT*** configuration) for further use later in test.\ -When the action is debugged using a Runner via NUnit test, it's important to pass the element search criteria into the action: +The following will create a runner with all types of reports disabled (except manual step reports): ```csharp -runner.Run(action, By.Id("phone")); -``` - -After the Addon is uploaded to TestProject platform this will be done via UI. - -#### Element Type - -Element Actions are made to be used on a specific Element Types. -Element Types are defined in TestProject using XPath to describe target elements similarities: - -
Web - Element Type -

- -It can be a simple definitions such as: - -```xml -//div -``` - -Or a more complex one, such as: - -```xml -//div[contains(@class, 'progressbar') and contains(@class, 'widget') and @role = 'progressbar'] -``` - -

- -
Android - Element Type -

- -It can be a simple definitions such as: - -```xml -//android.widget.Button -``` - -Or a more complex one, such as: - -```xml -//android.support.v7.widget.RecyclerView[contains(@resource-id, 'my_view') and .//android.widget.TextView[not(contains(@resource-id, 'average_value'))]] -``` - -

- -
iOS - Element Type -

- -It can be a simple definitions such as: - -```xml -//XCUIElementTypeButton +var runner = new RunnerBuilder("DEV_TOKEN") + .WithReportsDisabled() + .Build(); ``` -Or a more complex one, such as: - -```xml -//XCUIElementTypeSearchField[contains(@label = 'Categories')] -``` - -

- -It is up to the Action developer how to narrow and limit the list of element types that the action developed will be applicable to. - -## Crowd Code / Addon Proxy +### Disable driver commands reports -One of the greatest features of the TestProject environment is the ability to execute a code written by someone else.\ -It can be your account colleagues writing actions that you can reuse, or TestProject community users.\ -Developer must download a binary file with the proxy class for the Action he wants to execute. - -Assuming your account member uploaded the example Addon, named it ***Example Addon*** and you want to reuse it's code your Test.\ -To do so, you can download it's proxy DLL and use it like this: +Disabling commands reporting will result in tets reports with no steps, unless they are reported manually using `helper.Reporter.step()`. +The following will disable driver _commands_ reporting: ```csharp -var clearFieldsAction = ExampleAddon.CreateClearFieldsAction(); +var runner = new RunnerBuilder("DEV_TOKEN") + .WithDriverCommandReportingDisabled() + .Build(); ``` -Implemented *Execute()* method receives a _Helper_ instance as a parameter.\ -Via this helper, you can execute the proxy by invoking the ***ExecuteProxy*** method: - -```csharp -StepExecutionResult result = helper.ExecuteProxy(clearFieldsAction); -``` - -See examples: - -* [Web - Proxy Test](Web/Test/TestProject.SDK.Examples.Web.Test/Test/ProxyTest.cs) -* [Android - Proxy Test](Android/Test/TestProject.SDK.Examples.Android.Test/Test/ProxyTest.cs) -* [iOS - Proxy Test](IOS/Test/Test/ProxyTest.cs) -* [Generic - Proxy Test](Generic/Test/TestProject.SDK.Examples.Generic.Test/Test/ProxyTest.cs) - -## Packaging - - -In order to upload your Addons or Tests to TestProject you must prepare either a *DLL* file or a *ZIP* file:\ -* If your package only depends on TestProject SDK, you can upload the built *DLL* file to TestProject UI. -* If your package has other dependencies (e.g. DropBox API), Create a zip file from your project output (including dependencies, excluding TestProject SDK) and upload it to TestProject UI. - -Here's a simple example based on our [Web - Proxy Test](Web/Test/TestProject.SDK.Examples.Web.Test/Test/ProxyTest.cs) Example\ -To upload this test we will have to create a *ZIP* file containing 2 *DLL* files: -* TestProject.SDK.Examples.Web.Tests.dll - This is the project output. -* AddonProxy.dll - the addon proxy this test uses. - - -If your project contains external dependencies, follow these step to package it: -* Open a Terminal/PowerShell/Command prompt and navigate to the folder of your main project -* Run the following command: ```dotnet publish -o ./publish ./your-project.csproj```. make sure to use your project's csproj file. -* Open the publish folder we just created and zip all the files -> When using windows you can select all files and right click -> Send to -> Compressed archive.\ -> If using a different application to compress, always use Normal compression - -## Support - -For any further inquiries, please use TestProject support channels: +# License -* [Forum](https://forum.testproject.io/index.php/board,11.0.html) -* [Help Desk](https://support.testproject.io/) +TestProject SDK For C# is licensed under the LICENSE file in the root directory of this source tree. \ No newline at end of file diff --git a/Web/README.md b/Web/README.md index 3ef15c8..dc97d65 100644 --- a/Web/README.md +++ b/Web/README.md @@ -1,6 +1,6 @@ TestProject C\# SDK - Web Examples ====================================== -Tests & Addons examples. +Tests examples. You can find all information on how to use TestProject SDK in the [root of this repository](https://github.com/testproject-io/csharp-sdk-examples). \ No newline at end of file