Selenium cant find element on element that exists in page - c#

public class Sele
{
private IWebDriver driver;
private StringBuilder verificationErrors;
private string baseURL;
private bool acceptNextAlert = true;
public Sele( )
{
driver = new FirefoxDriver( );
baseURL = "https://www.youtube.com/";
verificationErrors = new StringBuilder( );
}
internal void LikeYoutubeVidWithAcc( string username, string password, string url )
{
driver.Navigate( ).GoToUrl( baseURL + "/" );
driver.FindElement( By.XPath( "(//button[#type='button'])[2]" ) ).Click( );
driver.FindElement( By.Id( "Email" ) ).Clear( );
driver.FindElement( By.Id( "Email" ) ).SendKeys( "UserName" );
driver.FindElement( By.Id( "next" ) ).Click( );
driver.FindElement( By.Id( "Passwd" ) ).Clear( );
driver.FindElement( By.Id( "Passwd" ) ).SendKeys( "Password" );
driver.FindElement( By.Id( "signIn" ) ).Click( );
driver.Navigate( ).GoToUrl( url );
driver.FindElement( By.XPath( "(//button[#type='button'])[25]" ) ).Click( );
}
}
I'm having trouble signing in to youtube using selenium, for some reason it can't find the password element in the page.
the error occurs at this line:
driver.FindElement( By.Id( "Passwd" ) ).Clear( );
Error message:
An unhandled exception of type 'OpenQA.Selenium.NoSuchElementException' occurred in WebDriver.dll
Additional information: Unable to locate element: {"method":"id","selector":"Passwd"}
I know the element exists on the page, yet selenium can't find it.
Page source when the error occurs:
<div class="card signin-card pre-shift no-name shift-form">
<div id="cc_iframe_parent"><iframe id="youtube" src="https://accounts.youtube.com/accounts/CheckConnection?pmpo=https%3A%2F%2Faccounts.google.com&v=-951713550&timestamp=1469398858532" style="visibility: hidden; width: 1px; height: 1px; position: absolute; top: -100px;"></iframe></div>
<div class="circle-mask" style="background-image: none;">
<canvas id="canvas" class="circle" width="96" height="96"></canvas>
</div>
<form novalidate="" method="post" action="https://accounts.google.com/signin/challenge/sl/password" id="gaia_loginform">
<input name="Page" value="PasswordSeparationSignIn" type="hidden">
<input name="GALX" value="bX35kb1ARtQ" type="hidden">
<input name="gxf" value="AFoagUWY2FAFLKhmD2_-vufme-BJ1jfACg:1469398858433" type="hidden">
<input name="continue" value="https://www.youtube.com/signin?next=%2F&hl=en&feature=sign_in_button&app=desktop&action_handle_signin=true" type="hidden">
<input name="service" value="youtube" type="hidden">
<input name="hl" value="en" type="hidden">
<input id="profile-information" name="ProfileInformation" value="APMTqulOYcx8i4BIKa7QX8vzLf8nHVle5wmAmPaLqZqa7bjp6poGeUD2zvzYvR46xap0wdwr2kQaxUuteML1f-hTwb_VW4ZDLaD0cYYzVup4THWBRGWMWv0" type="hidden">
<input id="_utf8" name="_utf8" value="☃" type="hidden">
<input name="bgresponse" id="bgresponse" value="!DwylDC1CEBfic73NLmFEPmLuo0jLmEwCAAAAH1IAAAAFCgASXF5p4wpYu2Whl5kDy5GtZSOFmQEOdst3NYj0yd4fKBLZxl94_2g92h7yeFimnFaHcZosa1A6tveg3lkaz-HEnxsgWWDRAptp3hXbMHf10f_l5URE4mup4YdMKniavQDRHw1mYbNpaTFcVbTQhb2Fq8zAY89pRskujAVj_FVIMin3uw8U3Ncz0sjSkkSBbSi7TneLgUGXSI-GHNUS6uVJGKfqXUCSMkdDA2d71bq-oANdlKwxKOyCAAIkcNAwwuROjGY1wiWaMRofROyHO3PfRvpdwtKP0MfCUCvFU88cdyXKHt-xyJO76CR96U3E5loZGOFscMs8BCy2KpyjeyE6yGHVcSAMFI9NgQfT0Gv5E4687eD__44iyMRuyd4xUYcetZAL" type="hidden">
<input id="pstMsg" name="pstMsg" value="1" type="hidden">
<input id="dnConn" name="dnConn" value="" type="hidden">
<input id="checkConnection" name="checkConnection" value="youtube:254:1" type="hidden">
<input id="checkedDomains" name="checkedDomains" value="youtube" type="hidden">
<div class="form-panel first valid" id="gaia_firstform">
<div style="transition-delay: 0ms;" class="slide-out hide-form">
<div class="input-wrapper focused">
<div id="identifier-shown"></div>
<span role="alert" class="error-msg" id="errormsg_0_Email"></span>
</div>
<div style="display: none" id="identifier-captcha">
<input name="identifiertoken" id="identifier-token" value="" type="hidden">
<input name="identifiertoken_audio" id="identifier-token-audio" type="hidden">
<div class="audio-box">
<div id="playIdentifierAudio"></div>
</div>
<div id="captcha-box" class="captcha-box">
<div id="captcha-img" class="captcha-img" data-alt-text="Visual verification"></div>
<span class="captcha-msg">
Letters are not case-sensitive
</span>
</div>
<label for="identifier-captcha-input" class="hidden-label"></label>
<input id="identifier-captcha-input" name="identifier-captcha-input" class="captcha" placeholder="Enter the letters above" title="Type the characters you see or numbers you hear" type="text">
</div>
<input id="next" name="signIn" class="rc-button rc-button-submit" value="Next" type="submit">
<a class="need-help" href="https://accounts.google.com/signin/recovery?continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Fnext%3D%252F%26hl%3Den%26feature%3Dsign_in_button%26app%3Ddesktop%26action_handle_signin%3Dtrue&service=youtube&ignoreShadow=0&hl=en">
Need help?
</a>
</div>
</div>
<a href="https://accounts.google.com/ServiceLogin?continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Fnext%3D%252F%26hl%3Den%26feature%3Dsign_in_button%26app%3Ddesktop%26action_handle_signin%3Dtrue&service=youtube&hl=en" tabindex="-1">
<img id="back-arrow" class="back-arrow shift-form" aria-label="Back" tabindex="0" alt="Back" src="https://www.gstatic.com/images/icons/material/system/1x/arrow_back_grey600_24dp.png">
</a>
<div class="form-panel second">
<div style="transition-delay: 100ms;" class="slide-in">
<div>
<p style="display: none;" id="profile-name"></p>
<span id="email-display">email123456#gmail.com</span>
</div>
<div>
<div id="password-shown"><div>
<input name="Email" id="Email-hidden" spellcheck="false" class="hidden" value="" readonly="" autocomplete="off" type="email">
<label class="hidden-label" for="Passwd">Password</label>
<input id="Passwd" name="Passwd" placeholder="Password" class="" type="password">
</div></div>
</div>
<input id="signIn" name="signIn" class="rc-button rc-button-submit" value="Sign in" type="submit">
<label class="remember">
<input id="PersistentCookie" name="PersistentCookie" value="yes" checked="checked" type="checkbox">
<span>
Stay signed in
</span>
<div class="bubble-wrap" role="tooltip">
<div class="bubble-pointer"></div>
<div class="bubble">
For your convenience, keep this checked. On shared devices, additional precautions are recommended.
Learn more
</div>
</div>
</label>
<input name="rmShown" value="1" type="hidden">
<a id="link-forgot-passwd" class="need-help" href="https://accounts.google.com/signin/recovery?continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Fnext%3D%252F%26hl%3Den%26feature%3Dsign_in_button%26app%3Ddesktop%26action_handle_signin%3Dtrue&service=youtube&checkedDomains=youtube&checkConnection=youtube%3A254%3A1&pstMsg=1&Email=wageeh14032%40gmail.com&ignoreShadow=0&hl=en">
Forgot password?
</a>
</div>
</div>
<span id="inge" style="display: none" role="alert" class="error-msg">
Sorry, Google doesn't recognize that email. Create an account using that address?
</span>
<span id="timeoutError" style="display: none" role="alert" class="error-msg">
Something went wrong. Check your connection and try again.
</span>
</form>
</div>

Try this:
WebDriverWait wait = new WebDriverWait(driver, 10); //you can change 10 seconds to whatever it suits you the best.
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("Passwd")));

Related

Puppeteer.NET: Can't autopopulate field

I am a just starting out with Puppeteer.NET, and i can't get it to autofill a login page.
The HTML for the web site looks like this:
<div class="main-wrapper">
<div class="row">
<div class="column section col-md-8">
<div class="loginForm">
<img src="images/logo.svg" width="300">
<br /><br /><br />
<div style="color: #454550; font-family: 'Neuzeit Grotesk'; font-size: 16px; ">
Welcome back
</div>
<br />
<form action="/login?app=LM&var=au" method="POST" name="login-form" id="login-form">
<input type="hidden" name="_csrf" value="BQ2YoR3d-5P__6b5HfqlVOjv8YgTypKV92XA" />
<div class="form-group text-center">
<input type="text" name="username" id="login-form-username" placeholder="Username" class="form-control" required value="">
</div>
<div class="form-group text-center">
<input type="password" name="password" id="login-form-password" placeholder="Password" class="form-control" required>
</div>
<div class="text-center">
<button type="submit" class="btn btn-danger btn-lg btn-block">Login</button>
</div>
</form>
<div style="color: #808083; margin-top: 30px; font-family: 'Roboto2';">
Trouble logging in?
<img src="images/grey_line.svg" width="300">
Sign up
</div>
</div>
<div style="text-align: center; width:400px;">
<img src="images/logo.svg" width="300">
</div>
</div>
<div class="column section col-md-4">
<iframe width="100%" height="100%" frameBorder="0" src="https://"></iframe>
</div>
</div>
</div>
I am trying to get it to fill in the login and password fields, and press the login button.
I am doing it as:
var extra = new PuppeteerExtra();
var stealth = new StealthPlugin();
LaunchOptions options = new LaunchOptions
{
Headless = false,
ExecutablePath = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
};
Browser browser = extra.Use(stealth).LaunchAsync(options).Result;
string content = null;
using (Page page = browser.NewPageAsync().Result)
{
// do login screen
page.GoToAsync(url);
page.WaitForNavigationAsync();
page.WaitForSelectorAsync("username");
page.FocusAsync("username");
page.Keyboard.TypeAsync(login);
page.WaitForSelectorAsync("password");
page.FocusAsync("password");
page.Keyboard.TypeAsync(password);
page.ClickAsync("submit");
page.WaitForNavigationAsync();
content = page.GetContentAsync().Result;
}
I have tried changing the "username" to "#username" and some other variations, but nothing gets filled in. Ultimately, all I want to to login and then go to a specific page, and have a dump of the resultant HTML.
Also is there a easy way to just a text dump of the resultant HTML?
You can use the selectors #login-form-username and #login-form-password, those are the IDs.

How to insert text into texbox selenium c#

<div class="input-container">
<div class="form-group">
<div class="labelContainer">
<<p>Current Password<span>*</span></p>
</div>
<label for="currentPassword" class="sr-only">Current Password</label>
<input type="password" id="currentPassword" name="currentPassword" class="form-control" placeholder="Current Password" required="">
<i class="fa fa-lock icon-style" aria-hidden="true"></i>
</div>
<div class="form-group">
<div class="labelContainer">
<<p>Enter New Password<span>*</span></p>
</div>
<label for="newPassword" class="sr-only">New Password</label>
<input type="password" id="newPassword" name="newPassword" class="form-control" placeholder="New Password" required="">
<i class="fa fa-lock icon-style" aria-hidden="true"></i>
</div>
<div class="form-group">
<div class="labelContainer">
<<p>Confirm New Password<span>*</span></p>
</div>
<label for="confirmPassword" class="sr-only">Confirm New Password</label>
<input type="password" id="confirmPassowrd" name="confirmPassowrd" class="form-control" placeholder="Confirm Password" required="">
<i class="fa fa-lock icon-style" aria-hidden="true"></i>
</div>
Above is the html code, I would like to insert the current password into current password text field. I have tried two methods below and it is not workable it says element not visible.
(code 1 )driver.FindElement(By.Id("currentPassword")).SendKeys("testabc");
(code 2 )IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
jse.ExecuteScript("document.getElementById('currentPassword').value='testabc';");
Try to test for newPassword textfield instead of currentPassword textfield and it is working fine. only the currentPassword and confirmPassword textfield have error message element not visible.
Does anyone know what is the problem?
You may try this,
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("currentPassword"))).SendKeys("testabc");

How to store multiple textbox values into one application variable in c#

[code page="c#"]
Hdnano.Value = Application["AccountNum"].ToString();
$(document).ready(function() {
$("#ano").on("blur", function() {
var accountNum = $('textarea#ano').val();
$("#Hdnano").val(folioNum);
});
<html>
<body>
<form>
<div class="container">
<div class="row">
<div class="col-xs-3 col-lg-2">
SELECT bank name
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-3 col-lg-2">
father name
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
<div class="col-xs-3 col-lg-2">
father mobile no
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-3 col-lg-2">
mother name
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
<div class="col-xs-3 col-lg-2">
mother mobile no
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-3 col-lg-2">
Account numbers
</div>
<div class="col-xs-3 col-md-6 col-lg-6">
<textarea class="form-control" rows="5" id="fno"></textarea>
</div>
</div>
</div>
</form>
</body>
</html>
How to store multiple textbox values into one application variable ?
here Customer details which are select bank name ,father/mother name and mobile number into one application variable ,and the multiple account numbers which is in text area into second application variable ?I want to store values of customer into application variable and than want to pass this values onto other page which is also similar kind of this html page.How can I use here json string
You can name variables like array elements. Look at this:
<form action="" method="POST">
<input type="text" name="name1[first]">
<input type="text" name="name1[second]">
<input type="text" name="name1[third]">
<input type="text" name="name2[0]">
<input type="text" name="name2[1]">
<input type="submit">
</form>

pass textbox value as parameter to controller route

I'm trying to use a textbox value in controller route and am having some trouble with the syntax. Essentially, I have my end users selecting a file and then submitting the data to the api to process and send the data off. I have working static code below, but can't get the xml path to be dynamically populated via the textbox value.
note that (as far as I can tell) the forward slash at the end of the path is required since there is a dot in the file path.
#using (Html.BeginForm("", "api/food/dummy food file.xml/"))
{
<div class="row">
<div class="col-lg-6">
<label class="control-label">Select File</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" single>
</span>
</label>
<input id="food.filepath" name="food.filepath" type="text" class="form-control" readonly>
</div>
</div>
</div>
<br />
<div>
<button id = "btnSubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
}
I don't what the syntax would be, but I can't get something like the below to work.
#using (Html.BeginForm("", "api/food/" + food.filepath + "/"))
{
<div class="row">
<div class="col-lg-6">
<label class="control-label">Select File</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" single>
</span>
</label>
<input id="food.filepath" name="food.filepath" type="text" class="form-control" readonly>
</div>
</div>
</div>
<br />
<div>
<button id = "btnSubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
}
Because the form is rendered on server and the value food.filepath is on client, you cannot mix them. Changing form action according to client values need to be done on client with javascript.
You can remove the file from action a add it on submit javascript action, for example by changing BeginForm to this:
#using (Html.BeginForm("", "api/food/", FormMethod.Get, new { onSubmit = "this.dataset.act = this.dataset.act||this.action; this.action = this.dataset.act + this['food.filepath'].value" } ))

Disabling Submit-button(s) when HTML Select is empty

I am a programmer-to-be, currently working on a project at work.
My problem is this: I have 3 submit buttons (on the same form), that each call a different action. These buttons HAVE to be disabled, if the HTML Selector (dropdown) does not have any options to choose from.
My form currently looks like this:
<form asp-action="Index" method="post" onkeypress="return event.keyCode != 13;">
<div class="col-md-9">
<div class="form-group form-inline">
<label asp-for="OrderNumber">Order number: </label>
<input asp-for="OrderNumber" class="form-control" type="text" placeholder="Insert order number" autofocus />
</div>
<div>
<label>Delete</label>
<input asp-for="Deletion" type="checkbox" />
</div>
<div>
<div class="col-md-4">
<input class="btn btn-block" type="submit" name="action" value="Receive" />
</div>
<div class="col-md-4">
<input class="btn btn-block" type="submit" name="action" value="Start" />
</div>
<div class="col-md-4">
<input class="btn btn-block" type="submit" name="action" value="Finish" />
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group form-inline">
<label asp-for="ProfileId">Profile: </label>
<select asp-for="ProfileId" class="form-control">
#foreach (var p in Model.Profiles)
{
<option value="#p.ProfileId">#p.Name</option>
}
</select>
</div>
</div>
</form>
Thanks for any help, and if you need more information, or if this question is poorly described, do not hesitate to ask! :)
Give your buttons an id. Set them to be disabled (enabled="false").
Call a javascript function when the dropdownlist is changed.
Check the selectedIndex of the dropdownlist in the function that is called onchange and set the button accordingly.
I could write a function that would do it, but you wouldn't learn anything. If you do a bit of research, have a stab at writing the function, I'll fix it if it doesn't work.
Simply disable the form fields that need be depending on if the others have the same conditional requirements. You can give them a custom class and use some javascript code and toggle the class with some JS like so.
toggleAttribute = function(className,index){
var eLs = [].slice.call(document.getElementsByClassName(className),0);
for(var i=0; i<eLs.length; i++){
eLs[i].disabled=(index==0 ? false : true); //index 0 is for 'Yes'
}
}
I came up with a solution of my own using Razor.
My form now looks like this:
<form asp-action="Index" method="post" onkeypress="return event.keyCode != 13;">
<div class="col-md-9">
<div class="form-group form-inline">
<label asp-for="OrderNumber">Order number: </label>
<input asp-for="OrderNumber" class="form-control" type="text" placeholder="Insert order number" autofocus />
</div>
<div>
<label>Delete</label>
<input asp-for="Deletion" type="checkbox" />
</div>
<div>
<div class="col-md-4">
<input class="btn btn-block" type="submit" name="action" value="Receive"
#{ if (Model.Profiles.Count() == 0) { #: disabled="disabled"
} } />
</div>
<div class="col-md-4">
<input class="btn btn-block" type="submit" name="action" value="Start"
#{ if (Model.Profiles.Count() == 0) { #: disabled="disabled"
} } />
</div>
<div class="col-md-4">
<input class="btn btn-block" type="submit" name="action" value="Finish"
#{ if (Model.Profiles.Count() == 0) { #: disabled="disabled"
} } />
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group form-inline">
<label asp-for="ProfileId">Profile: </label>
<select asp-for="ProfileId" class="form-control">
#foreach (var p in Model.Profiles)
{
<option value="#p.ProfileId">#p.Name</option>
}
</select>
</div>
</div>
</form>
I added an if-statement, that checks if there is any profiles in my list of profiles. If there is none (0), it adds the disabled="disabled" attribute to my inputs.
Thanks to anyone that tried to assist me in solving this, and providing me with suggestions for a solution :)

Categories