Selenium webdriver IsTextPresent (on the page more than once) - c#

I am using selenium web driver to determine whether a string of text exists more than twice on a page, as it should only appear once.
I can use Assert.IsTrue(this.Driver.IsTextPresent("body", "string")), but I was looking for a while to see if the text was on the page more than once.

You can do this easily with FindElements:
driver.FindElements(By.XPath("//*[contains(text(),'TEXT')]")).Count;
If Count > 1, then the text is present more than once on the page.

Related

How to click on a autocomplete item from a list using Selenium and C#

The web page https://www.priceline.com/?tab=cars&vrid=7fb0c3635c8e8e7633afe152907a052e has an <input> element. When I click on it and start typing a <div> with a list of items below appears and I can choose from that list. But when I insert text into that <input> element i.e. the location field, where you see "CIty, Airport or Address" placeholder element on the webpage opened by Selenium, either by actually typing myself or via driver.FindElement(...).SendKeys(...), I see the text, but the list below is not showing.
I don't even know how to approach this. Do I need to configure the driver in a special way?
I assume there is some javascript that intercepts the typing and shows the list below. But, what can be the difference between typing in real life and through Selenium? What can I do?
Selenium Version
Selenium.WebDriver - 4.8.0
Selenium.WebDriver.ChromeDriver - 110.0.5481.7700
It is possible, the way you are doing it is not simulating typing into the input so the event listener that is listening for that simulation isn't being fired. Try this code below which simulates someone actually typing.
using OpenQA.Selenium.Interactions;
// Find the input element
IWebElement inputElement = driver.FindElement(By.Id("input-element-id"));
// Create an Actions object and send keys to the input element
Actions actions = new Actions(driver);
actions.MoveToElement(inputElement)
.Click()
.SendKeys("your text here")
.Perform();
The site is detecting Selenium use and blocking use of the site.
If you navigate to the site in a normal browser, typing in the search field works fine.
If you navigate to the site using Selenium and then use the site manually, the dropdown functionality still doesn't work. If you refresh the page, you get sent to a reCATPCHA page with the message, "Access to this page has been denied because we believe you are using automation tools to browse the website."
The desired element is a dynamic element, so to send some text e.g. Boston within City, Airport or Address field and click on the matching option you need to induce WebDriverWait for the ElementToBeClickable() and you can use either of the following Locator Strategies:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//input[#data-testid='startLocation-typeahead-input']"))).SendKeys("Boston");
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[#data-testid='typeahead-dropdown-card']//div[#role='option' and contains(., 'Boston')]"))).Click();
Browser Snapshot:

Selenium cannot locate Drop down located within modal

I'm trying to select a value from the drop down 'ddl_settpymtaction' but selenium cannot locate it within the modal that resides in.
CSS:
Selenium code
driver.FindElementById("btn_SettlementNew").Click();
var Action = driver.FindElementById("ddl_SettPymtAction");
var SelectElement2 = new SelectElement(Action);
SelectElement2.SelectByValue("EFT");
In selenium you should ALWAYS add some delay when performing async operations (such as a modal which loaded with animations + ajax calls)
Why? To get your page a chance to render itself and let selenium wait for the right time to inspect the page (after being rendered with the required elements)

C# Selenium WebDriver - Is it possible to check if a certain webpage is already opened in the browser?

I was wondering if it is possible to check with C# and selenium web driver if a certain webpage is opened in the default browser?
My idea is to link certain ticketing system's time tracker with toggl.
For instance - on click of the "Time Track" button in the ticketing system, the program to click the toggl start button programmatically, at the same time.
Yes, it's possible.
You can devise a solution that checks the default window's URL or title.
if (driver.Url == 'http://some_url') { /* you are there */ }
or
if (driver.Title == 'Some Title') { /* the window is open and currently there */ }
Now, if you are running a browser manually using your own browser, then expect Selenium to detect that, then i'm sorry, but that is not possible.
In addition to #sircapsalot answer:
This won't be enough since the goal is to
on click of the "Time Track" button in the ticketing system
First you should be sure that the page has been loaded and the IWebElement is clickable. Without going in some advanced usage (like JS validation of the page state), this should do the work just fine:
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
var myElement = wait.Until(x => x.FindElement(By.Id("timeTrackBtnId")));
if(myElement.Displayed)
myElement.Click();
Then go for the
program to click the toggl start button programmatically, at the same time
I'm not sure how you'll sync and how page's JS events will handle this simultaneous actions, but you can try with System.Threading. If the page is created by you maybe this second part (click button, click togl) is better to be handled in the JS code.

Selenium click link multiple times

I'm automating tests for our webapp in Selenium WebDriver for C#. One of our test scenarios identified an issue with clicking the save button multiple times resulting in multiple identical records.
The standard IWebElement.Click() causes Selenium to block until the page is fully loaded. That means by the time our second click comes around to executing, the postback has been performed and we're not on the form page anymore.
Does anyone know a means of 'manually' clicking an element that won't cause Selenium to block?
You could either wait for a predetermined amount of time for the page to load:
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
...or to be more dynamic and wait for your button to appear:
var driver = new WebDriver();
var wait = new WebDriverWait(driver, TimeSpan(0, 1, 0));
wait.Until(d => d.FindElement(By.Id("button"));
Source: https://stackoverflow.com/a/7811812/2006048
Selenium also has source code that is similar to the second method: http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/ExpectedConditions.cs
Let me know if it works out for you. I personally use these options with WatiN:
browser.WaitForComplete();
...or:
browser.WaitUntilContainsText("Text");
It's a shame Selenium does not have the first one.
If we use JavaScript to send our click events, Selenium will not be blocked and we can click multiple times. However, because our click triggers a page load, we cannot reference the element directly. Instead, we need to specify the location to click and then fire our click events.
Because our WebApp uses JQuery, I was able to use the code specified here:
How to simulate a click by using x,y coordinates in JavaScript?
So in the end our C# logic looks something like this:
IWebElement element = driver.findElement(By.id("foobar"));
Point point = element.Location;
IJavascriptExecutor jscript = (IJavascriptExecutor)driver;
jscript.executeScript("$(document.elementFromPoint(arguments[0], arguments[0])).click();", point.X, point.Y);
Although this sends the click event I'm not 100% sure that the element receives it; I'll run some experiments and see.
What you need to do is click via javascript. In java this is done like this:
IJavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", driver.findElement(By.id("gbqfd")));
executor.executeScript("arguments[0].click();", driver.findElement(By.id("gbqfd")));
I actually imagine it is very similar, this will not block selenium and you should be able to chain a few on before the page comes back.
if this newer approach is too slow you might be quicker doing it all in js, e.g.
IJavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.getElementById(id).click();");
executor.executeScript("document.getElementById(id).click();");

Getting url of a page once making a form submission

I am designing a winforms based testing app (which is based upon WatiN). I specify a page to test and the value to insert into a textbox, and then click the corresponding button.
Is it possible to add a query string to the request I make (when clicking button) and then get the URL of the next page? Based on this, I need to screen scrape it.
Not sure about Watin syntax, but in Watir (Ruby version) you can get URL of the page displayed in browser with
browser.url
Or do you need to get URL of the next page before you open it?
Based on your comment to AmitK, Ċ½eljko's answer is right.
In WatiN (and C#), the syntax is:
Console.WriteLine("The current page is:" + ie.Url.ToString());
(just in case: 'ie' is the browser reference, use whatever object you use to enter text and click buttons)
What exactly do you mean by "next page" ? Does the form when submitted redirect to another page? If so, you will receive a HTTP 302/303 status code with the URL of the next page.

Categories