Skip to content

Commit

Permalink
updated fill script to support multiple forms on the same page and no…
Browse files Browse the repository at this point in the history
… form at all (only fields)
  • Loading branch information
kspearrin committed Oct 4, 2016
1 parent 23274ef commit b60be97
Showing 1 changed file with 34 additions and 73 deletions.
107 changes: 34 additions & 73 deletions src/iOS.Extension/Models/FillScript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,109 +16,70 @@ public FillScript(PageDetails pageDetails, string fillUsername, string fillPassw

DocumentUUID = pageDetails.DocumentUUID;

var passwordFields = pageDetails.Fields.Where(f => f.Type == "password").ToArray();
var passwordForms = pageDetails.Forms.Where(form => passwordFields.Any(f => f.Form == form.Key)).ToArray();

PageDetails.Form loginForm = null;
PageDetails.Field username = null, password = null;
List<PageDetails.Field> usernames = new List<PageDetails.Field>();
List<PageDetails.Field> passwords = new List<PageDetails.Field>();

if(passwordForms.Any())
var passwordFields = pageDetails.Fields.Where(f => f.Type == "password").ToArray();
foreach(var form in pageDetails.Forms)
{
if(passwordForms.Count() > 1)
{
// More than one form with a password field is on the page.
// This usually occurs when a website has a login and signup form on the same page.
// Let's try to guess which one is the login form.

// First let's try to guess the correct login form by examining the form attribute strings
// for common login form attribute.
foreach(var form in passwordForms)
{
var formDescriptor = string.Format("{0}~{1}~{2}",
form.Value?.HtmlName, form.Value?.HtmlId, form.Value?.HtmlAction)
?.ToLowerInvariant()?.Replace('_', '-');

if(formDescriptor.Contains("login") || formDescriptor.Contains("log-in")
|| formDescriptor.Contains("signin") || formDescriptor.Contains("sign-in")
|| formDescriptor.Contains("logon") || formDescriptor.Contains("log-on"))
{
loginForm = form.Value;
break;
}
}

if(loginForm == null)
{
// Next we can try to find the login form that only has one password field. Typically
// a registration form may have two password fields for password confirmation.
var fieldGroups = passwordFields.GroupBy(f => f.Form);
var singleFields = fieldGroups.FirstOrDefault(f => f.Count() == 1);
if(singleFields.Any())
{
var singlePasswordForms = passwordForms.Where(f => f.Key == singleFields.Key);
if(singlePasswordForms.Any())
{
loginForm = singlePasswordForms.First().Value;
}
}
}
}
var passwordFieldsForForm = passwordFields.Where(f => f.Form == form.Key).ToArray();
passwords.AddRange(passwordFieldsForForm);

if(loginForm == null)
if(string.IsNullOrWhiteSpace(fillUsername))
{
loginForm = passwordForms.FirstOrDefault().Value;
continue;
}

password = pageDetails.Fields.FirstOrDefault(f =>
f.Form == loginForm.OpId
&& f.Type == "password");

username = pageDetails.Fields.LastOrDefault(f =>
f.Form == loginForm.OpId
&& (f.Type == "text" || f.Type == "email")
&& f.ElementNumber < password.ElementNumber);

if(loginForm.HtmlAction != null)
foreach(var pf in passwordFieldsForForm)
{
AutoSubmit = new Submit { FocusOpId = password.OpId };
var username = pageDetails.Fields.LastOrDefault(f => f.Form == pf.Form
&& f.ElementNumber < pf.ElementNumber && (f.Type == "text" || f.Type == "email" || f.Type == "tel"));
if(username != null)
{
usernames.Add(username);
}
}
}
else if(passwordFields.Count() == 1)

if(passwordFields.Any() && !passwords.Any())
{
// The page does not have any forms with password fields. Use the one password field on the page and the
// The page does not have any forms with password fields. Use the first password field on the page and the
// input field just before it as the username.

password = passwordFields.First();
if(password.ElementNumber > 0)
{
username = pageDetails.Fields.LastOrDefault(f =>
(f.Type == "text" || f.Type == "email")
&& f.ElementNumber < password.ElementNumber);
var pf = passwordFields.First();
passwords.Add(pf);

if(username == null)
if(!string.IsNullOrWhiteSpace(fillUsername) && pf.ElementNumber > 0)
{
var username = pageDetails.Fields.LastOrDefault(f => f.ElementNumber < pf.ElementNumber
&& (f.Type == "text" || f.Type == "email" || f.Type == "tel"));
if(username != null)
{
username = pageDetails.Fields[password.ElementNumber - 1];
usernames.Add(username);
}
}
}

Script = new List<List<string>>();

if(username != null)
foreach(var username in usernames)
{
Script.Add(new List<string> { "click_on_opid", username.OpId });
Script.Add(new List<string> { "fill_by_opid", username.OpId, fillUsername });
}

if(password != null)
foreach(var password in passwords)
{
Script.Add(new List<string> { "click_on_opid", password.OpId });
Script.Add(new List<string> { "fill_by_opid", password.OpId, fillPassword });
}

if(passwords.Any())
{
AutoSubmit = new Submit { FocusOpId = passwords.First().OpId };
}
}

[JsonProperty(PropertyName = "script")]
public List<List<string>> Script { get; set; }
public List<List<string>> Script { get; set; } = new List<List<string>>();
[JsonProperty(PropertyName = "autosubmit")]
public Submit AutoSubmit { get; set; }
[JsonProperty(PropertyName = "documentUUID")]
Expand Down

0 comments on commit b60be97

Please sign in to comment.