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

Simple sauce pseudocode #25

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 15 additions & 0 deletions SauceExamples/AppiumOnDotNetFramework/app.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
71 changes: 71 additions & 0 deletions SauceExamples/Selenium.Nunit.Framework/Antipatterns/PoorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using FluentAssertions;
using NUnit.Framework;
using Selenium.Nunit.Framework.BestPractices.Pages;
using Selenium3.Nunit.Scripts.BestPractices.CrossBrowserExamples;

namespace Selenium.Nunit.Framework.Antipatterns
{
[TestFixture]
[TestFixtureSource(typeof(CrossBrowserData), "LatestConfigurations")]
[NonParallelizable]
[Ignore("Ignoring so that this can pass in CI")]
public class PoorTests : BaseCrossBrowserTest
{
public PoorTests(string browser, string version, string os) :
base(browser, version, os)
{
}

[Test]
public void EndToEndTest()
{
SauceReporter.SetBuildName("SCAntiPattern-NoSC");
var loginPage = new SauceDemoLoginPage(Driver);
//test loading of login page
loginPage.Open().IsLoaded.Should().BeTrue("the login page should load successfully.");
loginPage.UsernameField.Displayed.Should().BeTrue("the page is loaded, so the username field should exist");
loginPage.PasswordField.Displayed.Should().BeTrue("the page is loaded, so the password field should exist");

//test login with valid user
var productsPage = loginPage.Login("standard_user", "secret_sauce");
productsPage.IsLoaded.Should().BeTrue("we successfully logged in and the home page should load.");
productsPage.Logout();
loginPage.IsLoaded.Should().BeTrue("we successfully logged out, so the login page should be visible");

//test login with Locked Out user
productsPage = loginPage.Login("locked_out_user", "secret_sauce");
productsPage.IsLoaded.Should().BeFalse("we used a locked out user who should not be able to login.");

//test login with Problem user
productsPage = loginPage.Login("problem_user", "secret_sauce");
productsPage.IsLoaded.Should().BeTrue("we successfully logged in and the home page should load.");
productsPage.Logout();

//test login with invalid username
productsPage = loginPage.Login("fake_user_name", "secret_sauce");
productsPage.IsLoaded.Should().BeFalse("we used a invalid username who should not be able to login.");

//test login with invalid password
productsPage = loginPage.Login("standard_user", "fake_pass");
productsPage.IsLoaded.Should().BeFalse("we used an invalid password, so the user should not be able to login");

//validate that all products are present
productsPage = loginPage.Login("standard_user", "secret_sauce");
productsPage.IsLoaded.Should().BeTrue("we successfully logged in and the home page should load.");
productsPage.ProductCount.Should().Be(6,
"we logged in successfully and we should have 6 items on the page");

//validate that a product can be added to a cart
productsPage.AddFirstProductToCart();
productsPage.Cart.ItemCount.Should().Be(1, "we added a backpack to the cart");

//validate that user can checkout
var cartPage = productsPage.Cart.Click();
var checkoutOverviewPage = cartPage.Checkout().
FillOutPersonalInformation();
checkoutOverviewPage.FinishCheckout().IsCheckoutComplete.
Should().
BeTrue("we finished the checkout process");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using OpenQA.Selenium;
using Selenium.Nunit.Framework.BestPractices.Pages;

namespace Selenium.Nunit.Framework.BestPractices.Elements
{
public class CartComponent
{
private readonly IWebDriver _driver;
private string CartItemCounterText
{
get
{
try
{
return _driver.FindElement(By.XPath("//*[@class='fa-layers-counter shopping_cart_badge']")).Text;
}
catch (NoSuchElementException)
{
return "0";
}
}
}
public bool HasItems => int.Parse(CartItemCounterText) > 0;

public int ItemCount => int.Parse(CartItemCounterText);

public CartComponent(IWebDriver driver)
{
_driver = driver;
}

public CartComponent InjectUserWithItems()
{
((IJavaScriptExecutor)_driver).ExecuteScript("window.sessionStorage.setItem('session-username', 'standard-user')");
((IJavaScriptExecutor)_driver).ExecuteScript("window.sessionStorage.setItem('cart-contents', '[4,1]')");
_driver.Navigate().Refresh();
return this;
}

internal YourShoppingCartPage Click()
{
_driver.FindElement(By.Id("shopping_cart_container")).Click();
return new YourShoppingCartPage(_driver);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Common;
using Common.SauceLabs;
using OpenQA.Selenium;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public class BasePage
{
public readonly IWebDriver _driver;
private readonly string _baseUrl;

public SauceJavaScriptExecutor SauceJsExecutor =>
new SauceJavaScriptExecutor(_driver);

public Wait Wait => new Wait(_driver);
public string BaseUrl => _baseUrl;

public BasePage(IWebDriver driver)
{
_driver = driver;
_baseUrl = "https://www.saucedemo.com";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using OpenQA.Selenium;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public class CheckoutCompletePage
{
private readonly IWebDriver _driver;
public bool IsCheckedOut => _driver.Url.Contains("checkout-complete.html");


public CheckoutCompletePage(IWebDriver driver)
{
_driver = driver;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using OpenQA.Selenium;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
internal class CheckoutInformationPage : BasePage
{
public CheckoutInformationPage(IWebDriver driver) : base(driver)
{
}

private By CartCheckoutButtonLocator => By.CssSelector("[class='btn_primary cart_button']");

public CheckoutOverviewPage FillOutPersonalInformation()
{
Wait.UntilIsVisibleById("first-name").SendKeys("firstName");
_driver.FindElement(By.Id("last-name")).SendKeys("lastName");
_driver.FindElement(By.Id("postal-code")).SendKeys("zip");
_driver.FindElement(CartCheckoutButtonLocator).Click();
return new CheckoutOverviewPage(_driver);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using OpenQA.Selenium;
using Selenium.Nunit.Framework.BestPractices.Elements;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public class CheckoutOverviewPage : BasePage
{
public CheckoutOverviewPage(IWebDriver driver) : base(driver)
{
}
public CartComponent Cart => new CartComponent(_driver);

public OrderConfirmationPage FinishCheckout()
{
Wait.UntilIsVisibleByCss("[class='btn_action cart_button']").Click();
return new OrderConfirmationPage(_driver);
}

internal CheckoutOverviewPage Open()
{
//TODO duplication here with the URL. Also happening in YourShoppingCartPage
_driver.Navigate().GoToUrl($"{BaseUrl}/checkout-step-two.html");
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public enum Item
{
Backpack
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using OpenQA.Selenium;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public class OrderConfirmationPage : BasePage
{
public OrderConfirmationPage(IWebDriver driver) : base(driver)
{
}

public bool IsCheckoutComplete =>
Wait.UntilIsVisibleByClass("complete-header").Text == "THANK YOU FOR YOUR ORDER";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using OpenQA.Selenium;
using Selenium.Nunit.Framework.BestPractices.Elements;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public class ProductsPage : BasePage
{
private readonly string _pageUrlPart;

public ProductsPage(IWebDriver driver) : base(driver)
{
_pageUrlPart = "inventory.html";
}

public bool IsLoaded => Wait.UntilIsDisplayedById("inventory_filter_container");

private IWebElement LogoutLink => _driver.FindElement(By.Id("logout_sidebar_link"));

private IWebElement HamburgerElement => _driver.FindElement(By.ClassName("bm-burger-button"));

public int ProductCount =>
_driver.FindElements(By.ClassName("inventory_item")).Count;

public CartComponent Cart => new CartComponent(_driver);

public void Logout()
{
HamburgerElement.Click();
LogoutLink.Click();
}

internal ProductsPage Open()
{
_driver.Navigate().GoToUrl($"{BaseUrl}/{_pageUrlPart}");
return this;
}

public void AddFirstProductToCart()
{
Wait.UntilIsVisibleByCss("button[class='btn_primary btn_inventory']").Click();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Reflection;
using Common;
using OpenQA.Selenium;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
public class SauceDemoLoginPage : BasePage
{
public SauceDemoLoginPage(IWebDriver driver) : base(driver)
{
}

private readonly By _loginButtonLocator = By.ClassName("btn_action");
public bool IsLoaded => new Wait(_driver, _loginButtonLocator).IsVisible();
public IWebElement PasswordField => _driver.FindElement(By.Id("password"));
public IWebElement LoginButton => _driver.FindElement(_loginButtonLocator);
private readonly By _usernameLocator = By.Id("user-name");
public IWebElement UsernameField => _driver.FindElement(_usernameLocator);

public SauceDemoLoginPage Open()
{
_driver.Navigate().GoToUrl(BaseUrl);
return this;
}

internal Dictionary<string, object> GetPerformance()
{
var metrics = new Dictionary<string, object>
{
["type"] = "sauce:performance"
};
return (Dictionary<string, object>)((IJavaScriptExecutor)_driver).ExecuteScript("sauce:log", metrics);
}

public ProductsPage Login(string username, string password)
{
SauceJsExecutor.LogMessage(
$"Start login with user=>{username} and pass=>{password}");
var usernameField = Wait.UntilIsVisible(_usernameLocator);
usernameField.SendKeys(username);
PasswordField.SendKeys(password);
LoginButton.Click();
SauceJsExecutor.LogMessage($"{MethodBase.GetCurrentMethod().Name} success");
return new ProductsPage(_driver);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using OpenQA.Selenium;
using Selenium.Nunit.Framework.BestPractices.Elements;

namespace Selenium.Nunit.Framework.BestPractices.Pages
{
internal class YourShoppingCartPage : BasePage
{
public YourShoppingCartPage(IWebDriver driver) : base(driver)
{
}

public CartComponent Cart => new CartComponent(_driver);

internal CheckoutInformationPage Checkout()
{
Wait.UntilIsVisibleByCss("a[class='btn_action checkout_button']").Click();
return new CheckoutInformationPage(_driver);
}

internal YourShoppingCartPage Open()
{
_driver.Navigate().GoToUrl($"{BaseUrl}/cart.html");
return this;
}
}
}
Loading