Using XPaths within a Loop C# - c#

I currently have a piece of code that adds items into a bag with a 200 limit. But instead of having this limit in place i want to introduce a loop which will keep adding items until 200 is reached.
The issue i'm having is i'm not sure how i'd incorporate XPaths within my loop
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Interactions;
using System.Threading;
namespace Exercise1
{
class Mock1
{
static void Main()
{
IWebDriver webDriver = new ChromeDriver();
webDriver.Navigate().GoToUrl("http://www.asos.com/men/");
webDriver.Manage().Window.Maximize();
webDriver.FindElement(By.XPath(".//input[#data-testid='search-input']")).SendKeys("nike trainers");
webDriver.FindElement(By.XPath(".//button[#data-testid='search-button-inline']")).Click();
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(10));
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("article img")));
webDriver.FindElement(By.CssSelector("article img")).Click();
IWebElement Size = webDriver.FindElement(By.XPath(".//select[#data-id='sizeSelect']"));
SelectElementFromDropDown(Size, "UK 10 - EU 45 - US 11");
webDriver.FindElement(By.XPath("//*[#data-bind='text: buttonText']")).Click();
wait.Until(ExpectedConditions.ElementExists(By.XPath("//span[text()='Added']")));
webDriver.FindElement(By.XPath("//a[#data-testid='bagIcon']")).Click();
// I want to introduce a loop from here so that when item is added to the bag it keeps looping till 200 is reached.
wait.Until(ExpectedConditions.ElementExists(By.XPath("//select[contains(#class,'bag-item-quantity')]")));
string totalPrice = webDriver.FindElement(By.XPath("//span[#class='bag-subtotal-price']")).Text;
double pricePerItem = Convert.ToDouble(totalPrice.Substring(1));
int priceLimit = 200;
double noOfQuantity = priceLimit / pricePerItem;
IWebElement qty = webDriver.FindElement(By.XPath("//select[contains(#class,'bag-item-quantity')]"));
SelectElementFromDropDown(qty, Math.Floor(noOfQuantity).ToString());
wait.Until(ExpectedConditions.ElementExists(By.XPath("//button[#class='bag-item-edit-update']")));
webDriver.FindElement(By.XPath("//button[#class='bag-item-edit-update']")).Click();
// webDriver.Quit();
}
private static void SelectElementFromDropDown(IWebElement ele, string text)
{
SelectElement select = new SelectElement(ele);
select.SelectByText(text);
}
}
}

If I have understood your question properly, You want to use loop to add items until 200 limit is reached. In this case, you can simply adapt your code something like this
Assuming below line (first line) returns you total price:
string totalPrice = webDriver.FindElement(By.XPath("//span[#class='bag-subtotal-price']")).Text;
double total = Convert.ToDouble(totalPrice)
while(total > 200)
{
//code for adding items.
//update total price
total = Convert.ToDouble(webDriver.FindElement(By.XPath("//span[#class='bag-subtotal-price']")).Text);
}

Related

Assert.AreEqual Issue with validation error c# Selenium

I'm having issues with my Assert.AreEqual My code is validating whether an validation error I'm expecting is correct or not. But in my Assert.AreEqual and validationError are throwing up an exception.
You can see the validation error if you go onto https://energy.gocompare.com/gas-electricity then click on the continue button without entering any information in any of the fields
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(10));
IWebElement error = wait.Until(ExpectedConditions.ElementExists(By.XPath("//div[contains(#class, 'validation-error')]")));
Assert.AreEqual("Excpected validation error text", validationError.TextTrim());
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Interactions;
using System.Threading;
namespace Exercise1
{
class RunPath
{
static void Main()
{
IWebDriver webDriver = new ChromeDriver();
webDriver.Navigate().GoToUrl("https://energy.gocompare.com/gas-electricity");
webDriver.Manage().Window.Maximize();
String title = webDriver.Title;
String expectedTitle = "Utilities from Go Compare";
if (title.Contains(expectedTitle))
{
Console.WriteLine("Tile is matching with expected value");
}
else
{
throw new Exception("Title does not match");
}
String someText = webDriver.FindElement(By.XPath("//h1[#class='c-header__heading']")).Text;
String expectedHeader = "Switch today and save on your energy bills";
if (someText.Contains(expectedHeader))
{
Console.WriteLine("title matches");
}
else
{
throw new Exception("Title does not match");
}
webDriver.FindElement(By.XPath(".//button[#type = 'submit']")).Click();
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(10));
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.XPath("//div[contains(#class, 'validation-error')]")));
Assert.AreEqual("Expected validation error text", validationError.TextTrim());
Instead of this :
Assert.AreEqual("Excpected validation error text", validationError.TextTrim());
try this :
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.XPath("//div[contains(#class, 'validation-error')]")));
Assert.AreEqual("Please provide your postcode, as different regions have different fuel prices.", country.Text.Trim());
UPDATE :
If you want to do it without Nunit. As per our discussion
You can follow these steps :
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.XPath("//div[contains(#class, 'validation-error')]")));
String errorMsg = country.Text();
try{
if(errorMsg.Trim().Contains("Please provide your postcode, as different regions have different fuel prices."))
Console.WriteLine("Yes matched");
}
catch(Exception ex)
{
Console.WriteLine("Error msg did not match with the exact error msg");
}

Selenium c# find element select element exception

I'm fairly new to c# and writing a simple selenium code which will go onto www.asos.com. I then click on the country on the right hand side by finding the xpath. When I click on the country I want to change the country to 'india' and the currency to 'USD', and then select my preference.
I'm getting exception for driver.FindElement, SelectElement, SelectByValue previously when using java I wasn't getting these exceptions.
Exception I see for driver = The name driver doesn't exist in the current context
SelectElement = the type or namespace name 'SelectElement' could not be found
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace Exercise1
{
class Program
{
static void Main(string[] args)
{
IWebDriver webDriver = new ChromeDriver(#"Path to my chrome driver defined here");
webDriver.Navigate().GoToUrl("www.asos.com");
driver.FindElement(By.XPath("//*[#id="chrome - header"]/header/div[2]/div/ul/li[3]/div/button')]")).Click();
var country = driver.FindElement(By.Id("country"));
var select_country = new SelectElement(country);
select_country = SelectByValue("India");
var currency = driver.FindElement(By.Id("currency"));
var select_currency = new SelectElement(currency);
select_currency = SelectByValue("$ USD");
driver.FindElement(By.XPath("//*[#id="chrome - header"]/header/div[5]/div[2]/div/section/form/div[3]/button")).Click();
}
}
driver.FindElement(By.XPath("//*[#id="chrome - header"]/header/div[5]/div[2]/div/section/form/div[3]/button")).Click();
The erro in quotation marks, try:
driver.FindElement(By.XPath("//*[#id='chrome - header']/header/div[5]/div[2]/div/section/form/div[3]/button")).Click();
Use the value of the option in the html. Also call the select on the select element. For example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace Exercise1
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver= new ChromeDriver(#"Path to my chrome driver defined here");
driver.Navigate().GoToUrl("www.asos.com");
driver.FindElement(By.XPath("//*[#id='chrome - header']/header/div[2]/div/ul/li[3]/div/button')]")).Click();
var country = driver.FindElement(By.Id("country"));
var select_country = new SelectElement(country);
select_country.SelectByValue("IN");
var currency = driver.FindElement(By.Id("currency"));
var select_currency = new SelectElement(currency);
select_currency.SelectByValue("2");
driver.FindElement(By.XPath("//*[#id='chrome - header']/header/div[5]/div[2]/div/section/form/div[3]/button")).Click();
}
}
You may also want to throw in some waits to give the page time to load.

Exception 'Element should have been select but was div' C# selenium

I'm getting an exception with a piece of code. My code is adding an item to a bag then I want to select the quantity of the item. When I click on the quantity on the drop down menu to select 2.
My code throws an exception on this line:
IWebElement Qty = webDriver.FindElement(By.Id("bagApp"));
SelectElementFromDropDown(Qty, "2");
Element should have been select but was div.
This piece of code is designed to click on the drop down menu.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Interactions;
using System.Threading;
namespace Exercise1
{
class Exercise3
{
static void Main()
{
IWebDriver webDriver = new ChromeDriver();
webDriver.Navigate().GoToUrl("http://www.asos.com/men/");
webDriver.Manage().Window.Maximize();
webDriver.FindElement(By.XPath(".//input[#data-testid='search-input']")).SendKeys("nike trainers");
webDriver.FindElement(By.XPath(".//button[#data-testid='search-button-inline']")).Click();
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("article img")));
webDriver.FindElement(By.CssSelector("article img")).Click();
IWebElement Size = webDriver.FindElement(By.XPath(".//select[#data-id='sizeSelect']"));
SelectElementFromDropDown(Size, "UK 10.5 - EU 45.5 - US 11.5");
webDriver.FindElement(By.XPath("//*[#data-bind='text: buttonText']")).Click();
webDriver.FindElement(By.XPath("//a[#data-testid='bagIcon']")).Click();
IWebElement Qty = webDriver.FindElement(By.Id("bagApp"));
SelectElementFromDropDown(Qty, "2");
webDriver.FindElement(By.XPath("//*[#data-bind='click: update']")).Click();
//int trainer = 145;
//while (trainer < 200){
// Console.WriteLine(trainer);
// trainer = trainer * 2;
//}
webDriver.Quit();
}
private static void SelectElementFromDropDown(IWebElement ele, string text)
{
SelectElement select = new SelectElement(ele);
select.SelectByText(text);
}
}
}
You drop down is made of Divs and spans, Select class will not help you in this case.
You can try this code :
IList<IWebElement> options= webDriver.FindElements(By.CssSelector("li[class*='select2-results__option']"));
foreach (IWebElement element in options){
if(element.GetText().Equals("2")){
element.Click();
}
}
Note that before trying to select value from drop down , you have to click on down arrow button for that you can use this code :
webDriver.FindElement(By.CssSelector("span#select2-d2bx-container+span")).Click()
You should use explicit wait as you are moving to new page for this operation.
You can select the webelement as below
//Explicit wait is added to ensure that my bag item section is loaded successfully
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementExists(By.XPath("//select[contains(#class,'bag-item-quantity')]")));
IWebElement qtyElement = webDriver.FindElement(By.XPath("//select[contains(#class,'bag-item-quantity')]"));
SelectElementFromDropDown(qtyElement,"2");
The error is occurring because you are using the SelectElement class on an HTML element that is not a SELECT, a DIV in this case.
In order to select the desired option, you need to click the dropdown to open it and then click the desired option from the dropdown. Since you will likely be selecting options more than once, it's a good idea to put the code to do that into a function.
public void SelectOption(string s)
{
new WebDriverWait(webDriver, TimeSpan.FromSeconds(5)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector($"span[title='{s}']"))).Click();
}
Then call it like
webDriver.FindElement(By.CssSelector("span.select2")).Click();
SelectOption("2");

Selenium C# Can't find ID or Title

I manage to open a firefox browser, go to http://www.google.com/ search for "Bath Fitter". When i see a bunch of links, i want to in fact click on an item of the top menu provided by Google, Images. Images is located next to Map Videos News...
How can i have it click on Images?
Below is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
namespace SeleniumHelloWorld
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = null;
try
{
driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.google.com/");
driver.Manage().Window.Maximize();
IWebElement searchInput = driver.FindElement(By.Id("gbqfq"));
searchInput.SendKeys("Bath Fitter");
searchInput.SendKeys(Keys.Enter);
searchInput.FindElement(By.Name("Images"));
searchInput.Click();
driver.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception ****" + e.ToString());
}
}
}
}
More specifically you can also write your selector pointing from Top Navigation. This is the XPath.
.//*[#id='hdtb_msb']//a[.='Images']
try this;
driver.FindElement(By.XPath(".//*[#id='hdtb_msb']//a[.='Images']"));
EDIT:
Even though the selectors above were correct your code was not working because of the second page was taking too long to load. There you need to wait for the the element to be in ready state and an implicit wait is needed. Change the code in your try block and replace with mine and try
driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.google.com/");
driver.Manage().Window.Maximize();
IWebElement searchInput = driver.FindElement(By.Id("gbqfq"));
searchInput.SendKeys("Bath Fitter");
searchInput.SendKeys(Keys.Enter);
//this is the magic
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
By byImage = By.XPath(".//*[#id='top_nav']//a[.='Images']");
IWebElement imagElement =
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists(byImage));
imagElement.Click();
Try something like this...
IList<IWebElement> links = driver.FindElements(By.TagName("a"));
links.First(element => element.Text == "Images").Click();

Select element issue - webdriver - c#

I'm getting the below error while running in NUnit,
I'm finding an element and storing it in a variable, and while trying to select the element, i'm getting the error. Tried using in this way
IWebElement fromitem = WebDriver.FindElement(By.Id("from")); but same error persists.
Is there any way i can select the element?
Note : I verified the element id with firebug, there seems to be no problem with it.
The code below,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.Events;
using OpenQA.Selenium.Support.PageObjects;
namespace SeleniumTests
{
[TestFixture]
public class Sel
{
public static IWebDriver WebDriver;
private String baseURL;
[SetUp]
public void SetupTest()
{
WebDriver = new FirefoxDriver();
baseURL = "http://www.x-rates.com/calculator.html";
}
[TearDown]
public void TeardownTest()
{
WebDriver.Quit();
}
[Test]
public void newtest()
{
WebDriver.Navigate().GoToUrl(baseURL + "/");
var fromitem = WebDriver.FindElement(By.Id("from"));
var toitem = WebDriver.FindElement(By.Id("to"));
var fromval = new SelectElement(fromitem); //Error occurs
var toval = new SelectElement(toitem);
fromval.SelectByText("USD - US Dollar");
toval.SelectByText("INR - Indian Rupee");
WebDriver.FindElement(By.LinkText("Currency Calculator")).Click();
var curval = WebDriver.FindElement(By.CssSelector("span.ccOutputRslt")).GetAttribute("Value");
var expectedValue = 61.456825;
Thread.Sleep(900);
Assert.AreEqual(expectedValue, curval.Trim());
}
}
}
The SelectElement class can only be used with actual HTML <select> elements. In the page you provided, the element in question is an <input> element, with functionality added through CSS and JavaScript to enable it to act like a drop-down list. As such, attempting to use it with the SelectElement class will throw an exception indicating that the element is not of the correct type.
The "File does not exist" error message is a red herring. It's only there because NUnit is trying to show you the line of source code where the exception is thrown, which is a part of the WebDriver source code. The exception thrown by that line of code should be displayed somewhere within NUnit, which should contain the appropriate informational message.

Categories