I have a code which triggers 5 console apps (same code base different location).
public static void RunLoadGenInstances(int loadGenInstanceCount, string exePath)
{
try
{
for (int i = 1; i < loadGenInstanceCount; i++)
{
Thread.Sleep(1000);
Process.Start(exePath + i + #"\bin\Debug\wm_uk_hr_loadgen.exe");
Thread.Sleep(1000);
}
}
catch (Exception ex)
{
}
}
Each of the exe inilitializes the ChromeDriver.exe from their own executable path and opens up Chrome.
ChromeOptions options = new ChromeOptions();
options.AddUserProfilePreference("download.default_directory", file_path);
options.AddUserProfilePreference("disable-popup-blocking", "true");
options.AddArguments("--disable-extensions");
options.AddArguments("--start-maximized");
ChromeDriverService service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
service.SuppressInitialDiagnosticInformation = true;
service.HideCommandPromptWindow = true;
string url = HRSSUrl;
chromeDriver = new ChromeDriver(service, options);
Thread.Sleep(500);
chromeDriver.Navigate().GoToUrl(url);
Console.WriteLine("Enter uid");
IWebElement idWait = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("__control0-user")));
IWebElement id = chromeDriver.FindElement(By.Id("__control0-user"));
id.SendKeys(c4cUserId);
Console.WriteLine("uid entered");
Console.WriteLine("Enter pwd");
IWebElement passWait = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("__control0-pass")));
IWebElement pass = chromeDriver.FindElement(By.Id("__control0-pass"));
pass.SendKeys(c4cPassword);
Console.WriteLine("pwd entered");
Console.WriteLine("click login");
IWebElement loginWait = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("__control0-logonBtn")));
IWebElement login = chromeDriver.FindElement(By.Id("__control0-logonBtn"));
login.Click();
Problem is- Chrome is able to launch and navigate to URL but it is stuck on Sign In page. This happens in 4 console apps except 1, which runs fine. Below is the exception message which I get from the failed apps.
Enter uid
at OpenQA.Selenium.Support.UI.DefaultWait`1.ThrowTimeoutException(String exce
ptionMessage, Exception lastException)
at OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition)
at wm_uk_hr_loadgen.Program.SelectAuthenticationDropDown() in c:\UK-HR\LoadGe
n-MultiInstance\LoadGen1\Program.cs:line 273
at wm_uk_hr_loadgen.Program.Main(String[] args) in c:\UK-HR\LoadGen-MultiInst
ance\LoadGen1\Program.cs:line 105
Any help? Please let me know if any details needed.
Thanks,
Souvik
Related
Trying to write a test that checks if some words are on the page.
I'm getting a no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id='webform - submission - questionnaire - form - ajax']/section[2]"} message and the test for textIsOnThePage fails, everything else passes. Haven't used C# for a long time and trying out testing for the first time, what am I missing with textIsOnThePage ? This is the Xpath that the browser gives me.
public class Tests
{
IWebDriver driver;
String test_url = "http://mytesturl.com";
private readonly Random _random = new Random();
public void start_browser()
{
driver = new EdgeDriver(#"C:\Users\ADMIN\Downloads\edgedriver_win64");
driver.Manage().Window.Maximize();
}
//I run some tests on the page
public void test_page()
{
driver.Url = test_url;
driver.Navigate().GoToUrl("http://mytesturl.com");
Thread.Sleep(5000);
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
try {IWebElement sButton2 = driver.FindElement(By.XPath("//button[#class='agree-button eu-cookie-compliance-secondary-button']"));
js.ExecuteScript("arguments[0].click()", sButton2);
} catch (Exception) { }
for (int a = 0; a < 10; a++)
{
Thread.Sleep(2500);
//I call out my method
TextIsOnThePage("weigh", "weight");
Thread.Sleep(2500);
}
private void TextIsOnThePage(string textToFind, string warning)
{
driver.Url = test_url;
driver.Navigate().GoToUrl("http://mytesturl.com");
Thread.Sleep(5000);
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
var element = driver.FindElement(By.XPath("//*[#id='webform - submission - questionnaire - form - ajax']/section[2]"));
if (!string.IsNullOrEmpty(element.Text) && element.Text.Contains(textToFind))
{
Console.WriteLine("Text for " + warning + "is present");
}
else
{
Console.WriteLine(warning + " test failed");
}
}
public void close_Browser()
{
driver.Quit();
}
}
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System;
using System.IO;
using System.Threading;
namespace TallyWhatsappsender
{
public class Class1
{
OpenQA.Selenium.IWebDriver chrome_driver = null;
public String InitProcess(String contact,String file_route,String title,String chrome_binary)
{
try
{
if (!System.IO.File.Exists(file_route))
{
return "Error : Attachment not found!";
}
if (!System.IO.File.Exists(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "chromedriver.exe")))
{
return "Error : Chromedriver.exe executable not found!\n chromedriver.exe file is missing\n update or reinstalling may fix the problem";
}
var chrome_driver_service = ChromeDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory, "chromedriver.exe");
chrome_driver_service.HideCommandPromptWindow = true;
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.UnhandledPromptBehavior = UnhandledPromptBehavior.Accept;
if (File.Exists(chrome_binary))
{
chromeOptions.BinaryLocation = chrome_binary;
}
chrome_driver = new ChromeDriver(chrome_driver_service, chromeOptions);
IJavaScriptExecutor javaScriptExecutor = (IJavaScriptExecutor)chrome_driver;
foreach (string ct in contact.Split(','))
{
if (string.IsNullOrEmpty(ct.Trim()))
{
break;
}
if(ct.Trim().Length != 12)
{
if (!(chrome_driver is null)) chrome_driver.Quit();
return "Error : Invalid contact number-" + ct;
}
chrome_driver.Url = "https://web.whatsapp.com/send?phone=" + ct.Trim();
try
{
chrome_driver.SwitchTo().Alert().Accept();
}
catch (NoAlertPresentException e1)
{
Console.WriteLine(e1.Message);
}
try
{
WebDriverWait wait = new WebDriverWait(chrome_driver, System.TimeSpan.FromSeconds(60));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='main']/footer/div[1]/div[2]/div/div[2]")));
}
catch (WebDriverTimeoutException)
{
continue;
}
//sending file
IWebElement file_open = chrome_driver.FindElement(By.XPath("//*[#id='main']/footer/div[1]/div[1]/div[2]/div/div/span"));
javaScriptExecutor.ExecuteScript("arguments[0].click();", file_open);
chrome_driver.FindElement(By.CssSelector("input[type='file']")).SendKeys(file_route);
WebDriverWait wait2 = new WebDriverWait(chrome_driver, System.TimeSpan.FromSeconds(30));
wait2.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='app']/div/div/div[2]/div[2]/span/div/span/div/div/div[2]/span/div/div/span")));
IWebElement file_send = chrome_driver.FindElement(By.XPath("//*[#id='app']/div/div/div[2]/div[2]/span/div/span/div/div/div[2]/span/div/div/span"));
javaScriptExecutor.ExecuteScript("arguments[0].click();", file_send);
Thread.Sleep(1000);
//sending text
IWebElement typebox = chrome_driver.FindElement(By.XPath("//*[#id='main']/footer/div[1]/div[2]/div/div[2]"));//:chrome_driver.FindElements(By.CssSelector("div[class ='_3u328 copyable-text selectable-text']"))[0];
typebox.SendKeys(title);
IWebElement text_send = chrome_driver.FindElement(By.XPath("//*[#id='main']/footer/div[1]/div[3]/button/span"));
javaScriptExecutor.ExecuteScript("arguments[0].click();", text_send);
Thread.Sleep(3000);
}
//chrome_driver.Quit();
return "Process finished";
}
//catch (Exception ex)
//{
// if (!(chrome_driver is null)) chrome_driver.Quit();
// return ex.Message;
//}
}
}
}
I am using the above code for exporting a PDF file from tally and send it through Whatsapp Automatically.
I am facing a problem :
Every time I use this option a new tab of chrome opens and closes after sending file, because of new window it asks me to login to whatsapp every time , I think it will sort out if it do not close after sending file or when I activate it , it goes automatically to the previously opened Web.Whatsapp.com so that I will not need authentication each time.
please help me out into this .
Thanks in advance
Every time you call chrome_driver = new ChromeDriver(chrome_driver_service, chromeOptions); a new tab opens.
Try separating the initiating process and the sending process.
For example, your InitProcess method could look like the following:
public InitProcess(String chrome_binary)
{
try
{
if (!System.IO.File.Exists(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "chromedriver.exe")))
{
return "Error : Chromedriver.exe executable not found!\n chromedriver.exe file is missing\n update or reinstalling may fix the problem";
}
var chrome_driver_service = ChromeDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory, "chromedriver.exe");
chrome_driver_service.HideCommandPromptWindow = true;
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.UnhandledPromptBehavior = UnhandledPromptBehavior.Accept;
if (File.Exists(chrome_binary))
{
chromeOptions.BinaryLocation = chrome_binary;
}
chrome_driver = new ChromeDriver(chrome_driver_service, chromeOptions);
return "Intiated";
}
}
And then you could add a Send function:
public String Send(String contact, String file_route, String title)
{
try
{
IJavaScriptExecutor javaScriptExecutor = (IJavaScriptExecutor)chrome_driver;
foreach (string ct in contact.Split(','))
{
if (string.IsNullOrEmpty(ct.Trim()))
{
break;
}
if(ct.Trim().Length != 12)
{
if (!(chrome_driver is null)) chrome_driver.Quit();
return "Error : Invalid contact number-" + ct;
}
chrome_driver.Url = "https://web.whatsapp.com/send?phone=" + ct.Trim();
try
{
chrome_driver.SwitchTo().Alert().Accept();
}
catch (NoAlertPresentException e1)
{
Console.WriteLine(e1.Message);
}
try
{
WebDriverWait wait = new WebDriverWait(chrome_driver, System.TimeSpan.FromSeconds(60));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='main']/footer/div[1]/div[2]/div/div[2]")));
}
catch (WebDriverTimeoutException)
{
continue;
}
//sending file
IWebElement file_open = chrome_driver.FindElement(By.XPath("//*[#id='main']/footer/div[1]/div[1]/div[2]/div/div/span"));
javaScriptExecutor.ExecuteScript("arguments[0].click();", file_open);
chrome_driver.FindElement(By.CssSelector("input[type='file']")).SendKeys(file_route);
WebDriverWait wait2 = new WebDriverWait(chrome_driver, System.TimeSpan.FromSeconds(30));
wait2.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='app']/div/div/div[2]/div[2]/span/div/span/div/div/div[2]/span/div/div/span")));
IWebElement file_send = chrome_driver.FindElement(By.XPath("//*[#id='app']/div/div/div[2]/div[2]/span/div/span/div/div/div[2]/span/div/div/span"));
javaScriptExecutor.ExecuteScript("arguments[0].click();", file_send);
Thread.Sleep(1000);
//sending text
IWebElement typebox = chrome_driver.FindElement(By.XPath("//*[#id='main']/footer/div[1]/div[2]/div/div[2]"));//:chrome_driver.FindElements(By.CssSelector("div[class ='_3u328 copyable-text selectable-text']"))[0];
typebox.SendKeys(title);
IWebElement text_send = chrome_driver.FindElement(By.XPath("//*[#id='main']/footer/div[1]/div[3]/button/span"));
javaScriptExecutor.ExecuteScript("arguments[0].click();", text_send);
Thread.Sleep(3000);
return "Process finished";
}
}
}
Now you call InitProcess only once at the beginning of you program and Send every time you want to send the file.
I want to save session of whatsapp web so I do not have to scan qr-code every time I open whatsapp web. I use:
options.AddArgument("--user-data-dir=" + FolderPathToStoreSession)
but the qr-code appear again.
Here is the method to open whatsapp web for first time to scan qr code and save it to folder:
public static int OpenNewChrome(
string Website,
int TimeToWaitInMinutes,
string FolderPathToStoreSession)
{
ChromeOptions options = null;
ChromeDriver driver = null;
try
{
//chrome process id
int ProcessId = -1;
//time to wait until open chrome
var TimeToWait = TimeSpan.FromMinutes(TimeToWaitInMinutes);
ChromeDriverService cService = ChromeDriverService.CreateDefaultService();
//hide dos screen
cService.HideCommandPromptWindow = true;
options = new ChromeOptions();
//session file directory
options.AddArgument("--user-data-dir=" + FolderPathToStoreSession);
driver = new ChromeDriver(cService, options, TimeToWait);
//set process id of chrome
ProcessId = cService.ProcessId;
driver.Navigate().GoToUrl(Website);
FRM_MSG f2 = new FRM_MSG();
DialogResult r = f2.ShowDLG(" ",
"Did you successfully finish scan bardcode?",
FRM_MSG.MSGIcon.Question,
FRM_MSG.BTNS.Two,
new string[] { "Yes Finish", "Cannot scan qr-code" });
if (driver != null)
{
driver.Close();
driver.Quit();
driver.Dispose();
}
if (r == DialogResult.Yes)
return ProcessId;
return -1;
}
catch (Exception ex)
{
if (driver != null)
{
driver.Close();
driver.Quit();
driver.Dispose();
}
driver = null;
throw ex;
}
}
and here is method to restore session:
public static int OpenOldChrome(
string Website,
int TimeToWaitInMinutes,
string FolderPathToStoreSession)
{
ChromeOptions options = null;
ChromeDriver driver = null;
try
{
//chrome process id
int ProcessId = -1;
//time to wait until open chrome
var TimeToWait = TimeSpan.FromMinutes(TimeToWaitInMinutes);
ChromeDriverService cService = ChromeDriverService.CreateDefaultService();
//hide dos screen
cService.HideCommandPromptWindow = true;
options = new ChromeOptions();
//session file directory
options.AddArgument("--user-data-dir=" + FolderPathToStoreSession);
driver = new ChromeDriver(cService, options, TimeToWait);
//set process id of chrome
ProcessId = cService.ProcessId;
Thread.Sleep(50000);
FRM_MSG f2 = new FRM_MSG();
DialogResult r = f2.ShowDLG(" ",
"Did you wnat to exit?",
FRM_MSG.MSGIcon.Question,
FRM_MSG.BTNS.Two,
new string[] { "Yes", "No" });
if (driver != null)
{
driver.Close();
driver.Quit();
driver.Dispose();
}
if (r == DialogResult.Yes)
return ProcessId;
return -1;
}
catch (Exception ex)
{
if (driver != null)
{
driver.Close();
driver.Quit();
driver.Dispose();
}
driver = null;
throw ex;
}
}
The problem as I said the qr-code appear again, I want to scan qr-code only once
I use google chrome version 74, web driver v 3.141.0.
Do check if the profile folder is correct . An old thread here mention that you need to add \Default to the profile path.
Have you try adding this to see if this helps
options.addArguments("chrome.switches", "--disable-extensions")
I keep getting a StaleElementReferenceException error when I try to find all links and navigate through them in my console application, I have the following code and tried all day to fix it yesterday but with no result:
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Starting the browser...");
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.site.ro");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Gathering the Links...");
List<IWebElement> links = new List<IWebElement>();
try
{
foreach (IWebElement item in driver.FindElements(By.TagName("a")))
{
try
{
if (item.Displayed == true)
{
item.Click();
Console.WriteLine("Item is displayed \a\n" + "Navigating to link...");
} else
{
continue;
}
Random r1 = new Random();
Random r2 = new Random();
Random r3 = new Random();
var last = r3.Next(1, 10) * 700;
var mseconds = r2.Next(1, 10) * 500;
var time = mseconds + r1.Next(1, 10) * 300;
Console.WriteLine("Waiting for " + (time + last) + " miliseconds before next link");
System.Threading.Thread.Sleep(time + last);
driver.Navigate().Back();
System.Threading.Thread.Sleep(2000);
}
catch (Exception e2)
{
Console.WriteLine(e2);
Console.ReadLine();
}
}
}
catch (Exception e1)
{
Console.WriteLine(e1);
Console.ReadLine();
}
Console.WriteLine("Test finished.");
driver.Quit();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
}
driver.FindElements(By.TagName("a")) is finding for you all the links on the page.
Then you are going to the another page using the first link : item.Click();
Finally you are going back driver.Navigate().Back();
But that's not the initial page (by selenium's opinion). And all the links stored at the first step are gone because your initial page is gone. That's why you can't click the second of them.
You need to refind all the links after each driver.Navigate().Back();
Or better store all the hrefs to a list like linksList.Add(Item.getAttribute("href")); and use stored hrefs.
The code looks lengthy but it's a simple program.
I have built a console app (TakeScreenshots) that will take website screenshots from firefox, chrome & ie in that order & save them in a folder. When I manually run TakeScreenshots.exe, all 3 screenshots are saved.
Now, I have built another console app (MyApp) that will execute TakeScreenshots.exe. But in this way, only the firefox screenshot is saved and not of the other 2. There are no exceptions. It just says "Process Complete". I guess, MyApp is not waiting for the TakeScreenshots to complete.
How can I fix this.
[TakeScreenshots will later be placed in few remote computers & run by MyApp]
TakeScreenshots code:
private static string[] WebDriversList = ["firefox","chrome","internetexplorer"];
private static void TakeAPic()
{
string url = "http://www.google.com";
string fileNamePrefix = "Test";
string snapSavePath = "D:\\Pics\\";
foreach (string wd in WebDriversList)
{
IWebDriver NewDriver = null;
switch (wd.ToLower())
{
case "firefox":
using (NewDriver = new FirefoxDriver())
{
if (NewDriver != null)
{
CaptureScreenshot(NewDriver, url, fileNamePrefix, snapSavePath);
}
}
break;
case "chrome":
using (NewDriver = new ChromeDriver(WebDriversPath))
{
if (NewDriver != null)
{
CaptureScreenshot(NewDriver, url, fileNamePrefix, snapSavePath);
}
}
break;
case "internetexplorer":
using (NewDriver = new InternetExplorerDriver(WebDriversPath))
{
if (NewDriver != null)
{
CaptureScreenshot(NewDriver, url, fileNamePrefix, snapSavePath);
}
}
break;
}
if (NewDriver != null)
{
NewDriver.Quit();
}
}
}
private static void CaptureScreenshot(IWebDriver driver,string url,string fileNamePrefix,
string snapSavePath)
{
driver.Navigate().GoToUrl(url);
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ICapabilities capabilities = ((RemoteWebDriver)driver).Capabilities;
ss.SaveAsFile(snapSavePath + fileNamePrefix + "_" + capabilities.BrowserName + ".png",
ImageFormat.Png);
}
MyApp code:
static void Main(string[] args)
{
ExecuteTakeScreenshot();
Console.WriteLine("PROCESS COMPLETE");
Console.ReadKey();
}
private static void ExecuteTakeScreenshot()
{
ProcessStartInfo Psi = new ProcessStartInfo("D:\\PsTools\\");
Psi.FileName = "D:\\PsTools\\PsExec.exe";
Psi.Arguments = "/C \\DESK101 D:\\Release\\TakeScreenshots.exe";
Psi.UseShellExecute = false;
Psi.RedirectStandardOutput = true;
Psi.RedirectStandardInput = true;
Process.Start(Psi).WaitForExit();
}
Update:
It was my mistake. Initially WebDriversPath was assigned "WebDrivers/". When I changed it to the actual path "D:\WebDrivers\", it worked. But I still dont understand how it worked when TakeScreenshots.exe was run manually and it doesn't when run from another console
In similar problems I have had success with waiting for input idle first. Like this:
Process process = Process.Start(Psi);
process.WaitForInputIdle();
process.WaitForExit();
You could try this. For me it was needed to print a pdf using Adobe Reader and not close it to early afterwards.
Example:
Process process = new Process();
process.StartInfo.FileName = DestinationFile;
process.StartInfo.Verb = "print";
process.Start();
// In case of Adobe Reader the following statement is needed:
process.WaitForInputIdle();
process.WaitForExit(2000);
process.WaitForInputIdle();
process.Kill();