OpenQA.Selenium.NoSuchElementException was unhandled + C# + Another Website - c#

I am new to selenium, currently exploring on how it works. Started using it for ASP.NET application, i am using C# Selenium driver, IE Driver server ( 32 bit as it's faster than 64 bit)
I navigated to a application there I am clicking a link which should take me to ANOTHER WEBSITE where I have to find a textbox and clear it and enter some text (SendKeys) and then click a button.
When it goes to a another website from main website, It's unable to find the element ( I tried using by.ID and by.Name). I made sure element is available on the webpage. As recommened I used ImplicitlyWait but no luck, tried thread.sleep() no lucK.. Does the test needs to be on the same website which launched initially ?.. Below is my code snippet.. Please help me..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using System.Threading;
namespace mySelenium
{
class Program
{
private static void Main(string[] args)
{
IWebDriver driver = new InternetExplorerDriver(#"C:\Users\msbyuva\Downloads\IEDriverServer_Win32_2.45.0\");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("http://MyorgName.org/Apps/Sites/2015/login.aspx");
IWebElement userNameTxtBox = driver.FindElement(By.Id("ContentPlaceHolder1_Login1_UserName"));
userNameTxtBox.SendKeys("MSBYUVA");
IWebElement passwordTxtBox = driver.FindElement(By.Id("ContentPlaceHolder1_Login1_Password"));
passwordTxtBox.SendKeys("1234");
var myButton = driver.FindElement(By.Id("ContentPlaceHolder1_Login1_LoginButton"));
myButton.Click();
var EMailLink = driver.FindElement(By.LinkText("Email Testing Link"));
EMailLink .Click();
//Thread.Sleep(10000);
// -- HERE IT IS THROWING ERROR (ANOTHER WEBSITE AFTER CLICKING HYPERLINK)
var toEmailAddress = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$txtTo"));
toEmailAddress.Clear();
toEmailAddress.SendKeys("msbyuva#gmail.com");
var chkEmailAttachment = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$ChkAttachMent"));
chkEmailAttachment.Click();
var sendEmailButton = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_BtnSend"));
sendEmailButton.Click();
}
}
}

You need to switchTo newly opened window and set focus to it in order to send any commands to it
string currentHandle = driver.CurrentWindowHandle;
driver.SwitchTo().Window(driver.WindowHandles.ToList().Last());
After you done with newly opened window do(as need)
driver.Close();
driver.SwitchTo().Window(currentHandle );
More perfectly use PopupWindowFinder class
string currentHandle = driver.CurrentWindowHandle;
PopupWindowFinder popUpWindow = new PopupWindowFinder(driver);
string popupWindowHandle = popUpWindow.Click(EMailLink );
driver.SwitchTo().Window(popupWindowHandle);
//then do the email stuff
var toEmailAddress = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$txtTo"));
toEmailAddress.Clear();
toEmailAddress.SendKeys("msbyuva#gmail.com");
var chkEmailAttachment = driver.FindElement(By.Name("ctl00$ContentPlaceHolder1$ChkAttachMent"));
chkEmailAttachment.Click();
var sendEmailButton = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_BtnSend"));
sendEmailButton.Click();
}
}
}
//closing pop up window
driver.Close();
driver.SwitchToWindow(currentHandle);

Related

target frame detached Selenium c#

I wrote a class to automaticly translate text with selenium. When the translate button is pushed the page doesn't reload completly, I assume this happens with Javascript. I added a wait function to wait until the text shows up. However in 3 of the 10 generated translations I get the next error at line 30:
OpenQA.Selenium.WebDriverException: 'target frame detached (Session info: chrome=102.0.5005.115)'
Any solutions to fix it? thanks in advance!
class in c#
using System;
using System.Collections.Generic;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using System.Threading;
namespace WebscraperBasic
{
[Serializable]
public class vertalenNu
{
public static String translateText(IWebDriver driver, String text, String languageSource, String languageDestination)
{
// nl - en - de - fr -es -it
driver.Url = "https://www.vertalen.nu/zinnen/";
driver.FindElement(By.Id("vertaaltxt")).SendKeys(text);
SelectElement testt = new SelectElement(driver.FindElement(By.Id("tselectfrom")));
testt.SelectByValue(languageSource);
SelectElement test = new SelectElement(driver.FindElement(By.Id("tselectto")));
test.SelectByValue(languageDestination);
driver.FindElement(By.XPath("//input[#title='Vertaal']")).Click();
String technicalSheettext;
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3));
wait.Until(driver => driver.FindElement(By.Id("resulttxt")).Text != "");
IWebElement technicalSheet = driver.FindElement(By.ClassName("mt-translation-content"));
technicalSheettext = technicalSheet.Text;
}
catch
{
technicalSheettext = "translation failed";
}
driver.Close();
driver.Quit();
return technicalSheettext;
}
}
}

How to Find the reCAPTCHA element and click on it in c# Selenium

Hello everyone I need some help. There is URL: http://lisans.epdk.org.tr/epvys-web/faces/pages/lisans/petrolBayilik/petrolBayilikOzetSorgula.xhtml. As you can see in screenshot I need to click checkbox Captcha.
https://i.stack.imgur.com/xjXaA.png
Here 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.Chrome;
using OpenQA.Selenium.Support.UI;
namespace AkaryakitSelenium
{
class Program
{
private static string AkaryakitLink = "http://lisans.epdk.org.tr/epvys-web/faces/pages/lisans/petrolBayilik/petrolBayilikOzetSorgula.xhtml";
static void Main(string[] args)
{
IWebDriver driver = new ChromeDriver();
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
driver.Navigate().GoToUrl(AkaryakitLink);
var kategoriCol = driver.FindElements(By.CssSelector(".ui-selectonemenu-trigger.ui-state-default.ui-corner-right"));
var x = kategoriCol[3];
x.Click();
var deneme = driver.FindElement(By.Id("petrolBayilikOzetSorguKriterleriForm:j_idt52_1"));
deneme.Click();
var check = driver.FindElement(By.Id("recaptcha-anchor"));
check.Click();
}
}
}
And lastly this error that I am facing:
"OpenQA.Selenium.NoSuchElementException: 'no such element: Unable to
locate element: {"method":"css
selector","selector":"#recaptcha-anchor"}"
Thank you for your help.
The element you are looking for is inside an iframe :
//iframe[#title='reCAPTCHA']
first you need to switch to iframe like this :
new WebDriverWait(driver, TimeSpan.FromSeconds(3)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.XPath("//iframe[#title='reCAPTCHA']")));
then you can perform a click on it :
var check = driver.FindElement(By.Id("recaptcha-anchor"));
check.Click();
PS : captchas are not meant to be automated. since Captcha stands for CAPTCHA stands for the Completely Automated Public Turing test to tell Computers and Humans Apart.
You can not bypass captcha with Selenium.
It is designed to avoid automated access to web pages as described here and in many other places.

Building a selenium chrome webdriver with parameters and passing it to other methods in C#

I am new to Visual Studio 2015 and C#, my last coding exposure was about 15 years ago in a high school visual basic class. I have been asked to create a desktop application for someone else that goes to a webpage and performs some tasks. They want to click a couple buttons in the application instead of going to the page and don't want to see the browser or a command prompt.
I chose Selenium and C# in Visual Studio 2015 ent because it works with my needs for headlessly opening a chrome browser without the command prompt, also for office integration later. I did it like this:
//Sets up chrome webdriver with hidden console and headless mode.
ChromeOptions option = new ChromeOptions();
option.AddArguments("--headless");
var driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
//Add "option" in ChromeDriver() to activate headless chrome \/
IWebDriver driver = new ChromeDriver(driverService);
"option" left out of ChromeDriver() for testing, I need to see what the browser is doing at this step.
And it works, but it was created in a button_click event. My problem now is that I don't know the correct way to establish the driver with all the parameters needed outside of this method. I'd also like to use that same driver's session again without starting over.
My end goal is to have that button populate the form with the contents of a CheckedListBox (the only part of the page that changes and needs direct input) then another button sending the user's selection to the page and generating a report.
Here is the relevant part:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace Report_Tool
{
public partial class ReportToolUI : Form
{
//Sets the chrome webdriver.
public static IWebDriver Driver { get; set; }
public ReportToolUI()
{
InitializeComponent();
}
public void ReportToolUI_Load(object sender, EventArgs e)
{
}
public void getListButton_Click(object sender, EventArgs e)
{
//Sets up chrome webdriver with hidden console and headless mode.
ChromeOptions option = new ChromeOptions();
option.AddArguments("--headless");
var driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
//Add "option" in ChromeDriver() to activate headless chrome \/
IWebDriver driver = new ChromeDriver(driverService);
//Goes to obfuscated site.
driver.Navigate().GoToUrl("obfuscated");
}}}
What would be the correct way to create that webdriver once and call it in the different button_click methods?
Use a singleton:
public class Utils
{
private static IWebDriver _driver;
public static IWebDriver Driver {
get {
if (_driver == null) {
var service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
var options = new ChromeOptions();
options.AddArguments("--headless");
var commandTimeout = TimeSpan.FromSeconds(30);
_driver = new ChromeDriver(service, options, commandTimeout);
}
return _driver;
}
}
}
Then access the driver anywhere with Utils.Driver.

MultiThreading Variables C# -- Selenium

I am trying to automate the test for one of my websites using Selenium on C#. The website prompts the user for login credentials. It can only be done through multi threading.
I execute one thread to open the page in a special FireFox profile and another thread in parallel to simulate the press of ENTER.
The problem is the if I don't use multi threading, the code stops at opening the page as the website is not completely opened.
The driver is initiated in the first thread created. However it has to be used in the main method.
How can I pass an object created in a method (executed by a thread) in the main function?
Here's 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;
using OpenQA.Selenium.Support.UI;
using System.Collections.ObjectModel;
using System.Threading;
using System.IO;
using OpenQA.Selenium.Interactions;
using System.Windows.Forms;
namespace CRMTest1WithSelenium
{
class Program
{
public static IWebDriver OpenPage()
{
IWebDriver driver = null;
string path = #"C:\Users\ntouma\AppData\Roaming\Mozilla\Firefox\Profiles\nuxgc36b.CRMTester";
FirefoxProfile ffprofile = new FirefoxProfile(path);
driver = new FirefoxDriver(ffprofile);
driver.Navigate().GoToUrl("http://www.example.com");
return driver;
}
public static void pressEnter()
{
Thread.Sleep(6000);
System.Windows.Forms.SendKeys.SendWait("{ENTER}");
}
static void Main(string[] args)
{
IWebDriver driver2 = null;
driver2 = OpenPage();
// Thread driverCreation = new Thread(OpenPage);
// driverCreation.Start();
Thread login = new Thread(pressEnter);
login.Start();
Thread.Sleep(2000);
driver2.Manage().Window.Maximize();
IWebElement sales = driver2.FindElement(By.XPath("/html/body/div[4]/d"));
sales.Click();
IWebElement leads = driver2.FindElement(By.XPath("/html/body//div/div/ul/li[3]/span/span[2]/span/span[1]/span/a[1]"));
leads.Click();
Thread.Sleep(5000);
}
}
}
Well i don't understand your problem in 100%...
But i can suggest two solutions:
1) Use a static member that your login functions will use inside it.
2) Send a class(object) to the thread when you create one:
e.g:
var myObj = ...; Thread thread = new Thread(() => pressEnter(myObj)); thread.Start();

Screen Capture in C# using HtmlAgilityPack

Due to the lack of proper documentation, I'm not sure if HtmlAgilityPack supports screen capture in C# after it loads the html contents.
So is there a way I can more or less grab a screenshot using (or along with) HtmlAgilityPack so I can have a visual clue as to what happens every time I do page manipulations?
Here is my working code so far:
using HtmlAgilityPack;
using System;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
string urlDemo = "https://htmlagilitypack.codeplex.com/";
HtmlWeb getHtmlWeb = new HtmlWeb();
var doc = getHtmlWeb.Load(urlDemo);
var sentence = doc.DocumentNode.SelectNodes("//p");
int counter = 1;
try
{
foreach (var p in sentence)
{
Console.WriteLine(counter + ". " + p.InnerText);
counter++;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
}
}
Currently, it scrapes and output all the p of the page in the console but at the same time I want to get a screen grab of the scraped contents but I don't know how and where to begin.
Any help is greatly appreciated. TIA
You can't do this with HTML Agility Pack. Use a different tool such as Selenium WebDriver. Here is how to do it: Take a screenshot with Selenium WebDriver
Could you use Selenium WebDriver instead?
You'll need to add the following NuGet packages to your project first:
Selenium.WebDriver
Selenium.Support
Loading a page and taking a screenshot is then as simple as...
using System;
using System.Drawing.Imaging;
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
namespace SeleniumTest
{
class Program
{
static void Main(string[] args)
{
// Create a web driver that used Firefox
var driver = new FirefoxDriver(
new FirefoxBinary(), new FirefoxProfile(), TimeSpan.FromSeconds(120));
// Load your page
driver.Navigate().GoToUrl("http://google.com");
// Wait until the page has actually loaded
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 10));
wait.Until(d => d.Title.Contains("Google"));
// Take a screenshot, and saves it to a file (you must have full access rights to the save location).
var myDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(Path.Combine(myDesktop, "google-screenshot.png"), ImageFormat.Png);
driver.Close();
}
}
}

Categories

Resources