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.
<div class="p-card-wrppr" data-id="4250531">
<a class="p-card-chldrn-cntnr" href="/arko/men-3-adet-t3-tiras-bicagi-6-li-3-x-6-li-paket-p-4250531?boutiqueId=399802&merchantId=117834">
<div class="p-card-img-wr"><img class="p-card-img" src="https://img-trendyol.mncdn.com/assets/product/media/images/20191101/13/487069/16991825/1/1_org.jpg"></div>
<div>
<div class="stmp-box-wrppr">
<div class="stmp fc">free cargo</div>
</div>
<div class="cstm-stmp-box-wrppr"></div>
</div>
<div class="prdct-desc-cntnr-wrppr">
<div class="prdct-desc-cntnr">
<div class="prdct-desc-cntnr-ttl-w"><span class="prdct-desc-cntnr-ttl" title="ARKO">ARKO</span><span class="prdct-desc-cntnr-name hasRatings" title="Men 3 Adet T3 Tıraş Bıçağı 6'Lı (3 x 6'Lı Paket)">Product nameeee</span></div>
<div class="ratings">
<div class="star-w">
<div class="empty">
<div class="star"></div>
</div>
<div class="full" style="width: 100%; max-width: 100%;">
<div class="star"></div>
</div>
</div>
<div class="star-w">
<div class="empty">
<div class="star"></div>
</div>
<div class="full" style="width: 100%; max-width: 100%;">
<div class="star"></div>
</div>
</div>
<div class="star-w">
<div class="empty">
<div class="star"></div>
</div>
<div class="full" style="width: 100%; max-width: 100%;">
<div class="star"></div>
</div>
</div>
<div class="star-w">
<div class="empty">
<div class="star"></div>
</div>
<div class="full" style="width: 100%; max-width: 100%;">
<div class="star"></div>
</div>
</div>
<div class="star-w">
<div class="empty">
<div class="star"></div>
</div>
<div class="full" style="width: 67%; max-width: 100%;">
<div class="star"></div>
</div>
</div><span class="ratingCount">(21)</span></div>
</div>
<div class="prc-cntnr">
<div class="prc-box-orgnl">79,99 TL</div>
<div class="prc-box-sllng">59,78 TL</div>
</div>
<div class="prmtn-cntnr"></div>
</div>
</a>
<div class="fvrt-btn-wrppr"><i class="fvrt-btn"></i></div>
I can't pull the links of products on the shopping site
I updated the html code part :)
The problem still continues
I am trying to pull links of products on the page
some details-some details-some details-some details-some details-some details-some details-some details-some details
My code:
IWebElement link = driver.FindElement(By.ClassName("p-card-wrppr"));
link.FindElements(By.TagName("a"));
link.GetAttribute("href")
im new to umbraco and c#, I made a blog list in umbraco razor but how can i make a load more button funcionality?
i want when the user click the button load more 5 items to the list.
One way is the the users click the button update the query, but i would need to refresh the page.
Any Help would be great since im stuck on this one, and have no clue how to do this in umbraco.
#{
var selection = Model.Content.Children().Where(x => x.IsVisible()).Take(5).ToList();
}
<div class="container-fluid" style="padding-left: 117px;">
<div class="row" style="margin-top: 5em;">
<div class="col-lg-9 col-md-9 col-sm-9">
<!-- BLOG START -->
#while(selection.Any()){
var oneItem = selection.First();
selection.Remove(oneItem);
<div class="row">
<div class="col-md-4 col-sm-12" onclick="location.href='#oneItem.Url'" style="cursor:pointer">
<div class="card">
<img src="#Umbraco.TypedMedia(oneItem.GetPropertyValue<int>("imagemPublicacaoBlog")).Url" style="height: 15em;">
</div>
</div>
<div class="col-md-6 col-sm-12" onclick="location.href='#oneItem.Url'" style="cursor:pointer">
<span class="card-text qs-blog-direcao">#oneItem.GetPropertyValue("tipoDeDirecao")</span><br><br>
<span class="qs-blog-date-1page" id="qs-datetime">#(oneItem.GetPropertyValue<DateTime>("dataDePublicacaoBlog").ToString("dd MMMM yyyy",new CultureInfo("pt-PT")))</span>
<br>
<span class="qs-blog-publicado-por">#oneItem.GetPropertyValue("publicadoPorBlog") - OPINIÃO </span>
<span class="qs-blog-titulo-1page">#oneItem.GetPropertyValue("tituloBlog")</span>
</div>
<div class="col-md-12 col-sm-12 onclick="location.href='#oneItem.Url'" style="cursor:pointer"" style="margin-top:2em;">
<span class="qs-blog-resumo d-flex justify-content-start">#oneItem.GetPropertyValue("resumoBlog")</span>
<span class="d-flex justify-content-end"><a><img src=" /media/1027/icon_inf_verde.png"></a></span>
</div>
</div>
var twoItems = selection.Take(2).ToList();
if(twoItems.Any()){
<div class="row">
#foreach (var item in twoItems){
selection.Remove(item);
<div class="col-md-6 col-sm-12" onclick="location.href='#item.Url'" style="cursor:pointer">
<span class="card-text qs-blog-direcao-double">#item.GetPropertyValue("tipoDeDirecao")</span><br>
<img src="#Umbraco.TypedMedia(item.GetPropertyValue<int>("imagemPublicacaoBlog")).Url" style="height: 10em;margin-top: 2em;">
<div class="qs-blog-sideByside">
<span class="qs-blog-date-1page-double" id="qs-datetime">#(item.GetPropertyValue<DateTime>("dataDePublicacaoBlog").ToString("dd MMMM yyyy",new CultureInfo("pt-PT")))</span><br>
<span class="qs-blog-publicado-por-double"> #item.GetPropertyValue("publicadoPorBlog") - OPINIÃO </span>
</div>
<div class="qs-blog-titulo-1page-double">#item.GetPropertyValue("tituloBlog")</div>
<div class="qs-blog-resumo-blog d-flex justify-content-start">#item.GetPropertyValue("resumoBlog")</div>
<span class="d-flex justify-content-end"><a><img src=" /media/1027/icon_inf_verde.png"></a></span>
</div>
}
</div>
<br>
}
}
<!-- BLOG END -->
</div>
It could be something like this:
#{
int page = int.TryParse(Request["page"], out page) ? page : 0;
int pageSize = 5;
var selection = Model.Content
.Children()
.Where(x => x.IsVisible())
.Skip(page * pageSize)
.Take(pageSize)
.ToList();
}
<div class="container-fluid">
...
</div>
<a href="#Request.RawUrl.Split('?')[0]?page=#(page + 1)">
Load next #pageSize results
</a>
I have two views; Index and Giftworx. In the Index I have icons and when each is clicked it should direct user to a specific point in the GiftWorx page. I've tried the below code but it didnt work. Any help would be appreciated.
Index View:
<div class="col-md-4 w3_agileits_features_grid">
<div class="agileits_w3layouts_features_grid">
<div class="col-xs-4 agileits_w3layouts_features_gridl">
<div class="agile_feature_grid">
#* <i class="fa fa-gift" aria-hidden="true"></i>
</div>*#
<i class="fa fa-gift" aria-hidden="true"></i>
</div>
</div>
<div class="col-xs-8 agileits_w3layouts_features_gridr">
<h4>Who uses GiftWorx</h4>
<p>See who uses GiftWorx and more.</p>
</div>
<div class="clearfix"> </div>
</div>
</div>
GiftWorxView
<div class="why-convertible-box" id="GiftWorxUsers">
<div class="container" id="GiftWorxUsers">
<h1>Who uses GiftWorx<i class="fa fa-question-circle"></i></h1>
</div>
</div>
<div class="hoc container clear" id="GiftWorxUsers">
<div class="row">
<div class="col-md-2" style="padding: 2px;">
<div style="border: lightgrey solid thin; border-radius: 2px">
<img class="img-responsive" style="height:auto;" src="~/Content/myTemplate/Logos/1.jpg" />
</div>
</div>
<div class="col-md-2" style="padding: 2px;">
<div style="border: lightgrey solid thin; border-radius: 2px">
<img class="img-responsive" src="~/Content/myTemplate/Logos/17.jpg" />
</div>
</div>
<div class="col-md-2" style="padding: 2px;">
<div style="border: lightgrey solid thin; border-radius: 2px">
<img class="img-responsive" src="~/Content/myTemplate/Logos/15.jpg" />
</div>
</div>
This is a little bit tricky but should work fine. First I declare the variable with concatenated section of your page:
#{
var strLink = Url.Action("GiftWorxUsers", "GiftWorx") + "#GiftworxArea";
}
Then on your Index View, put this on your a href link:
<div class="agile_feature_grid">
<a href='#strLink'>
<i class="fa fa-gift" aria-hidden="true">
</i>
Link text here
</a>
</div>
Make sure you have an area in your View of Giftworx which has a name in this example: Giftworx by adding this piece of code:
<a name="GiftworxArea"></a>
<div class="col-md-4 w3_agileits_features_grid">
//Other stuffs here
</div>
Now when you click on that link, you will be directed on your page on that exact spot with a section name GiftworxArea.
I am trying post a simple list within a model back to the controller. its rendered correctly but on post its always empty. I noticed when I use #Html.Hidden for the id and name are different for instance id becomes TestExceptionDisplay_[0]__Exception and name becomes TestExceptionDisplay[0].Exception. So I use an input type and try to make the way it likes to render but it does not work. I tried partial view, editor templates, nothing seems to work. TestException Display is a very simple list of an object called public List<RunLogEntryTestExceptionDisplay> TestExceptionDisplay { get; set; }
public class RunLogEntryTestExceptionDisplay
{
public string Exception { get; set; }
}
Snippet in the view which uses a for loop to render list, list is rendered fine but on post TestExceptionDisplay is NULL always:
#if (Model.TestExceptionDisplay != null)
{
for (var i = 0; i < Model.TestExceptionDisplay.Count; i++)
{
<tr>
<td>
#Model.TestExceptionDisplay[i].Exception
#*#Html.HiddenFor(m => m.TestExceptionDisplay[i].Exception)*#
<input name="RunLogEntry.TestExceptionDisplay_[#i]__Exception" type="hidden" value="#Model.TestExceptionDisplay[i].Exception" />
</td>
</tr>
}
}
OR this does not even work with editor templates upon post
#if (Model.TestExceptionDisplay != null)
{
#Html.EditorFor(x => x.TestExceptionDisplay)
}
Editor Template in Shared\EditorTemplates with the exact name of RunLogEntryTestExceptionDisplay
#model RunLog.Domain.Entities.RunLogEntryTestExceptionDisplay
<div>
#Html.EditorFor(x => x.Exception)
#Html.HiddenFor(x => x.Exception)
</div>
Rendered HTML looks like below, I did not copy the entire list, PLEASE NOT THAT THE ID AND NAME SEEM TO RENDER IN A DIFFERENT NAMING CONVENTION. IT HAPPENS in both cases, if I use an editor template or a for loop. thanks
<input id="TestExceptionDisplay_9__Exception" name="TestExceptionDisplay[9].Exception" type="hidden" value=""1404 TestException - Parameters:Unable to calculate result, assay is not calibrated for Assay Number (135), Assay Version (5), Track (1), Lane (2), and Reagent Lot Number (26600LI06)"" />
Complete View:
#model RunLog.Domain.Entities.RunLogEntry
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/errorCode.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/testexception.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/runLogEntry.js")" type="text/javascript"></script>
<script type="text/javascript">
var runlogListErrorsUrl = '#Url.Action("ListErrorCodes", "RunLogEntry")';
</script>
<fieldset>
<legend>Enter a new Run Log Entry</legend>
#using (Html.BeginForm("Create", "RunLogEntry", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<div class="exception">#(ViewBag.ErrorMessage)</div>
<div class="bodyContent">
<span class="leftContent">Load List File (Select): </span><span class="rightContent">
<input type="file" name="file" id="file1" style="width: 500px" />
</span>
</div>
if (Model.LoadListStoredFileName != null)
{
<div class="bodyContent">
<span class="leftContent">Attached Load List: </span><span class="rightContent">
#Html.ActionLink(Model.LoadListFileName, "Download", new { #file = Model.LoadListStoredFileName })
</span>
</div>
}
<div class="bodyContent">
<span class="leftContent">Output File (Select): </span><span class="rightContent">
<input type="file" name="file" id="file2" style="width: 500px" />
</span>
</div>
if (Model.OutputStoredFileName != null)
{
<div class="bodyContent">
<span class="leftContent">Attached Output: </span><span class="rightContent">
#Html.ActionLink(Model.OutputFileName, "Download", new { #file = Model.OutputStoredFileName })
</span>
</div>
}
<div class="bodyContent">
<span class="leftContent">Import Files: </span>
<button name="submit" class="art-button" type="submit" value="Upload" style="width: 100px">
Upload</button>
<button name="submit" class="art-button" type="submit" value="Remove" style="width: 100px">
Remove</button>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Operator")
</span><span class="rightContent">
#Html.DropDownList("OperatorID", String.Empty)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Run ID")
</span><span class="rightContent">[Generated] </span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Run Start Date / Time")
</span><span class="rightContent">
#Html.EditorFor(model => model.RunDate)
#Html.DropDownList("Hour", ListHelpers.HourList())
:
#Html.DropDownList("Minute", ListHelpers.Minute15List())
#Html.DropDownList("AMPM", ListHelpers.AMPMList())
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("System")
</span><span class="rightContent">
#Html.DropDownList("SystemID", String.Empty)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Run Type")
</span><span class="rightContent">
#Html.DropDownList("RunTypeID", String.Empty)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Run Description")
</span><span class="rightContent">
#Html.TextAreaFor(model => model.RunDescription, new { style = "width: 600px; height=30px" })
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Assay Performance Issues")
</span><span class="rightContent">
#Html.DropDownList("AssayPerformanceIssues1", ListHelpers.YesNoList())
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Tests/Cycles Requested")
</span><span class="rightContent">
#Html.EditorFor(model => model.SPTestsRequested)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Tests/Cycles Completed")
</span><span class="rightContent">
#Html.EditorFor(model => model.SPTestsCompleted)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Run Status")
</span><span class="rightContent">
#Html.DropDownList("RunStatusID", String.Empty)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Assay")
</span><span class="rightContent">
#Html.ListBoxFor(model => model.SelectedAssayIDs, new MultiSelectList(RunLog.Domain.Lists.GlobalList.AssayListItems(), "ID", "Name", Model.SelectedAssayIDs))
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Error Code")
</span><span class="rightContent"><span id="ChildDialogLink" class="treeViewLink">Click
here to Select Error Codes</span>
<br />
<span id="ErrorCodeDisplay" style="cursor: pointer; text-decoration: underline;">#(Model.ErrorDescription)</span>
#Html.HiddenFor(model => model.ErrorDescription)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Test Exceptions")
</span><span class="rightContent"><span id="TestExceptionChildDialogLink" class="treeViewLink">
Click here to View Test Exceptions</span>
<br />
<span id="TestExceptionDisplayy"></span></span>
</div>
<div id="testExceptiontreeview" title="Dialog Title" style="font-size: 10px; font-weight: normal;
overflow: scroll; width: 800px; height: 450px;">
<div id="testExceptions">
</div>
<div id="inputTestExceptions">
<table class="grid" style="width: 450px; margin: 3px 3px 3px 3px;">
<thead>
<tr>
<th>
Exception String
</th>
<th>
Comment
</th>
</tr>
</thead>
#* #{var index = 0;}*#
#if (Model.TestExceptionDisplay != null)
{
for (var i = 0; i < Model.TestExceptionDisplay.Count; i++)
{
<tr>
<td>
#Model.TestExceptionDisplay[i].Exception
#Html.HiddenFor(m => m.TestExceptionDisplay[i].Exception)
</td>
</tr>
}
}
</table>
</div>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Service Entry Request")
</span><span class="rightContent">
#Html.DropDownList("ServiceRequest", ListHelpers.YesNoList())
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Problem Description")
</span><span class="rightContent">
#Html.TextArea("ProblemDescription", new { style = "width: 600px; height: 30px" })
</span>
</div>
<p>
<input id="LogType" type="hidden" value="Run" />
<input id="ID" type="hidden" value="0" />
#if (Model.ExitCode == "1")
{
#Html.Hidden("ExitCode", Model.ExitCode)
}
else
{
<input id="ExitCode" type="hidden" value='0' />
}
</p>
#Html.HiddenFor(model => model.MaxReplicateId)
#Html.HiddenFor(model => model.MinReplicateId)
#Html.HiddenFor(model => model.OutputFileName)
#Html.HiddenFor(model => model.OutputStoredFileName)
#Html.HiddenFor(model => model.LoadListFileName)
#Html.HiddenFor(model => model.LoadListStoredFileName)
#Html.HiddenFor(model => model.MinTestCompletionDate)
#Html.HiddenFor(model => model.MaxTestCompletionDate)
<div class="bodyContent">
<span class="leftContent"></span><span class="rightContent">
<button name="submit" class="art-button" type="submit" value="Create">
Create</button></span>
</div>
}
</fieldset>
<script src="#Url.Content("~/Scripts/exitCode.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/exitCode.js")" type="text/javascript"></script>
<div id="treeview" title="Dialog Title" style="font-size: 10px; font-weight: normal;
overflow: scroll; width: 800px; height: 450px;">
<div id="errorCodes">
#Html.RenderTree(CacheHelper.ErrorCodes(), ec => ec.Name, ec => ec.Children.ToList(), ec => (ec.ID).ToString(), null, "e")
</div>
<div id="inputReps" style="display: none;">
</div>
</div>
Why are you expecting the list in the model you receive to be populated?
The model on POST is populated only with data from the form - MVC creates a new instance of your model class and populates the fields it can match up.
Because of this, the stock way of making sure your lists are populated is to have a helper method which populates them. You can then call this from either the original Get or the Post method to repopulate the lists.
The only time you'd expect to get a list populated in your model by PMV on postback is when the details to rebuild the list are available in form elements.
It's possible I've missed it in your reams of code but I can't see you doing that anywhere.
You should initialize your list in your first method, then pass to post method.