I'm trying to automate TextNow using Selenium but when I add Username and password, I am getting an error "Username or Password is invalid". But, the same is working fine manually.
below is the code which i tried
static void Main(string[] args)
{
IWebDriver driver;
driver = new ChromeDriver("cromepath");
driver.Url = "https://www.textnow.com/messaging";
driver.Manage().Window.Maximize();
IWebElement userName = driver.FindElement(By.Id("txt-username"));//txt-password
IWebElement password = driver.FindElement(By.Id("txt-password"));
userName.SendKeys("username");
password.SendKeys("password");
IWebElement login = driver.FindElement(By.Id("btn-login"));
login.Click();
}
You mentioned you get an error that username / password are invalid. Are you sure you are sending the right credentials?
Your XPath is correct here, so waiting for element to exist is most likely issue
-- textnow.com does take a minute to load. You might also want to clear both WebElements before sending keys.
using OpenQA.Selenium.Support.UI;
// declare wait of 15 seconds
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
// wait for element to exist, then store it in username variable
var username = wait.Until(drv => drv.FindElement(By.Id("txt-username")));
// clear & send keys
username.Clear();
username.SendKeys("username");
The same approach can be repeated for password.
If you are still getting username / password invalid, and you are sure you are using correct credentials, then it's possible SendKeys() is happening too quickly & keystrokes are not all registering in the input fields..
You can wrap SendKeys() in a method to slowly send keys, in case the input entering too quickly is a problem:
public static void SlowlySendKeys(this IWebElement element, string text)
{
// first clear element
element.Clear();
// slowly send keys, wait 100ms between each key stroke
foreach (var c in text) {
element.SendKeys(c);
System.Threading.Thread.Sleep(100);
}
}
Then, you can call:
username.SlowlySendKeys("username");
This will slow down key strokes and work around issue where key strokes are sent too quickly.
Related
I am making a bot that list all the given assembled letters to make the players connect or build a word around that given value of assembled letters, im very new to selenium and still grasping the best practices thanks in advance. (https://jklm.fun "BombParty")
https://i.stack.imgur.com/wGyMd.png
What we want to achieve:
//locate the element (the one the center of that bomb)
//extract the elements displayed value (the label)
//Console Log that value
My Code:
ChromeOptions options = new ChromeOptions(); //creating chrome driver options to add some commands to remove the message "This is automated . . ."
options.AddAdditionalCapability("useAutomationExtension", true);
options.AddExcludedArgument("enable-automation");
options.AddArgument("window-size=1200x600");
var driver = new ChromeDriver(options); //declear our driver for us to automate and control
driver.Navigate().GoToUrl("https://jklm.fun/QVVC"); // go to our targeted uri
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(25); // wait for sometime to give our client to load
// let our user enter the username or join a game
while (true) // loop our funtion to locate and extract the given word
{
try
{
driver.FindElements(By.CssSelector("div.syllable")); //we did a FindElements because the label can change value over time and state another syllable
Console.WriteLine("Success!");
}
catch
{
Console.WriteLine("Failed!");
}
}
The Output of my Code:
Success!
What I Have tried:
var word = driver.FindElement(By.CssSelector("div.syllable"));
Console.WriteLine(word.Text.ToString());
The Result: Failed!
Update:
So i tried to get the value after it finds it and i will find it again,it was a success but it only returns this string, how to fix this?
The update
The problem is that I need to get the PID of IE browser instances so that I can close the IE browser(Working in C#).
I launched the IE browser using Selenium and then used Driver Service class as :-
InternetExplorerDriverService driverdetails = InternetExplorerDriverService.CreateDefaultService();
Console.WriteLine(driverdetails.Port);
The plan is to get the port and then have its child process. I am able to do so using a debugger by entering the value of Port manually. But, the port fetched by driverdetails.Port was not the actual port used by my driver.
Is there any was, I can find the Port for any given driver service?
For IE i have an alternative to launch IE and get the URL with port which says http://localhost:. However, this is not the case with other browsers. My want is to make the generic code and hence I am using the Driver Service object.
As far as I know, the InternetExplorerDriverService's ProcessID property gets the process ID of the running driver service executable, and we can't get the IE browser instance PID through the InternetExplorer webdriver. If you want to get the PID, you could try to use the Process class.
From your description, it seems that you want to close the IE tab or window by using the IE Webdriver. If that is the case, I suggest you could use InternetExplorerDriver WindowHandles to get the opened windows, then use the switchto method to switch the window and check the url or title, finally, call the Close method to close the IE window. Please refer to the following sample code:
private const string URL = #"https://dillion132.github.io/login.html";
private const string IE_DRIVER_PATH = #"D:\Downloads\webdriver\IEDriverServer_x64_3.14.0"; // where the Selenium IE webdriver EXE is.
static void Main(string[] args)
{
InternetExplorerOptions opts2 = new InternetExplorerOptions() { InitialBrowserUrl = "https://www.bing.com", IntroduceInstabilityByIgnoringProtectedModeSettings = true, IgnoreZoomLevel = true };
using (var driver = new InternetExplorerDriver(IE_DRIVER_PATH, opts2))
{
driver.Navigate();
Thread.Sleep(5000);
//execute javascript script
var element = driver.FindElementById("sb_form_q");
var script = "document.getElementById('sb_form_q').value = 'webdriver'; console.log('webdriver')";
IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
jse.ExecuteScript(script, element);
InternetExplorerDriverService driverdetails = InternetExplorerDriverService.CreateDefaultService(IE_DRIVER_PATH);
Console.WriteLine(driverdetails.Port);
// open multiple IE windows using webdriver.
string url = "https://www.google.com/";
string javaScript = "window.open('" + url + "','_blank');";
IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
jsExecutor.ExecuteScript(javaScript);
Thread.Sleep(5000);
//get all opened windows (by using IE Webdriver )
var windowlist = driver.WindowHandles;
Console.WriteLine(windowlist.Count);
//loop through the list and switchto the window, and then check the url
if(windowlist.Count > 1)
{
foreach (var item in windowlist)
{
driver.SwitchTo().Window(item);
Console.WriteLine(driver.Url);
if(driver.Url.Contains("https://www.bing.com"))
{
driver.Close(); //use the Close method to close the window. The Quit method will close the browser window and dispose the webdriver.
}
}
}
Console.ReadKey();
}
Console.ReadKey();
}
I'm trying to submit a from using c# to a website and am trying to get the response from the server as a message box after the data is sent. the website does redirect to another page to show an output.
What happens so far is the data is not submitted until I click OK on the message box that is displaying the data before it is send not after.
WebBrowser browser = new WebBrowser();
string target = "http://www.awebsite.com";
browser.Navigate(target);
browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(XYZ);
}
}
private void XYZ(object sender, WebBrowserDocumentCompletedEventArgs e) // fail was here.
{
WebBrowser b = (WebBrowser)sender;
string text = richTextBox1.Text.ToString();
if (text == null)
{
MessageBox.Show("the messgae was empty");
}
b.Document.GetElementById("idmsg").InnerText = richTextBox1.Text.ToUpper().ToString();
b.Document.GetElementById("idpassw").InnerText = ".....";
b.Document.GetElementById("idpagers").InnerText = id;
b.Document.GetElementById("Send").InvokeMember("click");
// allow server response time
System.Threading.Thread.Sleep(5000);
string output = b.Document.Body.OuterText.ToString();
MessageBox.Show(output);
}
I'v also tried adding another Document complete with the //allow server response time code but again did'nt send till OK was pressed.
what am I doing wrong?
You do it totally wrong. Never rely on the.Sleep(...). C# provides rich enough async environment, namely Task DoAsync(...) which is to be used somewhat like await DoAsync(). This guarantees that no code going below the DoAsync() would ever be executed unless the async operation either completed successfully, either failed with error. As such, by the time you'll get to the last MessageBox.Show(...), all the data would be there, displayed properly as expected.
I'm running a Selenium test in C# to open a URL, log in using a supplied username & password, then navigate to a page containing downloadable reports. See my code below (note: website names and usernames/passwords are withheld):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support;
using OpenQA.Selenium.Support.UI;
namespace SeleniumProject
{
class SeleniumTest
{
public static void Main(string[] args)
{
#region Constants
//User Account Information
const string username = "MyUsername";
const string password = "MyPassword";
//Initial Login Page URL and Elements
const string urlLogin = "MyURL";
const string usernameLoginName = "username";
const string passwordLoginName = "password";
const string submitLoginClassName = "btnAlign";
//Welcome Page Element
const string profileWelcomeClassName = "mstrLargeIconViewItemLink";
#endregion
int elementListIndex = 0;
IWebDriver driver = new InternetExplorerDriver();
driver.Manage().Window.Maximize();
driver.Navigate().GoToUrl(urlLogin);
driver.FindElement(By.Name(usernameLoginName)).SendKeys(username);
driver.FindElement(By.Name(passwordLoginName)).SendKeys(password);
driver.FindElement(By.ClassName(submitLoginClassName)).Click();
if (driver.Title == "Servicer Performance Profile Home. MicroStrategy")
{
try
{
driver.FindElement(By.ClassName(profileWelcomeClassName)).Click();
}
catch (NoSuchElementException ex)
{
//failed
}
}
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.XPath("//img[contains(#src,'images/freddiemac/sppdash/navigation-drawer-1.png')]")));
IReadOnlyList<IWebElement> elementList = driver.FindElements(By.XPath("//img[contains(#src,'images/freddiemac/sppdash/navigation-drawer-1.png')]"));
string mainHandle = driver.CurrentWindowHandle;
foreach (var element in elementList)
{
if (element.Displayed && elementListIndex == 5)
{
element.Click();
driver.FindElement(By.XPath("//div[contains(.,'EDR Overview')]")).Click();
break;
}
else
{
elementListIndex++;
}
}
}
}
}
What's happening is whenever I execute that last Click() event that's within the if statement nested inside of the foreach loop, instead of the normal behavior of the link opening a new tab in the same IE, it's opening as a new window and reverting back to a prior page. Normally, whenever I log into this website manually and click this link, a new tab is opened that contains another download link inside of it; that's the page I'm trying to get to.
I have no idea why this new browser window is opening with a prior page instead of even the target page I'm requesting. Could this have something to do with Selenium & IE11 not getting along? Another idea is the current login session expiring somehow, but this is all being executed in less than 10 seconds, so I wouldn't assume this is the issue.
Does anyone have any ideas?
This issue has been resolved. After many, many failed attempts at changing IE settings for handling new tabs, executing JavaScript onclick() events programmatically (instead of using native browser click commands), opening and switching between empty tabs, trying right-click keyboard commands, etc., the issue came down to IE simply not being compatible with what I was trying to do. First attempt with Google Chrome proved to be successful. The website behaved normally and links that were supposed to trigger a new tab indeed triggered the new tab.
My advice to those of you new to Selenium webdriver testing, whether your language is C# or something else, is to avoid Internet Explorer at all costs. Even with IE 11, none of what I was wanting to do worked. Test using Chrome as your first choice. Maybe it will save you three working days of troubleshooting and debugging.
I've looked extensively through Google and Stackoverflow, but i cant find a good way to implement keeping the browser open after a run and reuse it for the next run. I have it login, get text, but it closes after. I want to keep it open so I dont have relaunch the browser, login again and take more time than necessary. Simply want to use that same webpage, refresh/update the page, and get the new text(its dhtml). I have it to run every 10 seconds or so. Here what i have so far.
using (var driver = new ChromeDriver(""))
{
driver.Navigate().GoToUrl(#"");
// Get User Name field, Password field and Login Button
var userNameField = driver.FindElementByName("j_username");
var userPasswordField = driver.FindElementByName("j_password");
var loginButton = driver.FindElementByName("Submit");
// Type user name and password
userNameField.SendKeys("");
userPasswordField.SendKeys("");
// and click the login button
loginButton.Click();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.ClassName(""));
});
// Extract resulting message and save it into result.txt
string result = driver.FindElement(By.ClassName("")).Text;
}