Open webbrowser, auto complete form components and submit

50,749

Solution 1

I wrote an example for filling in an element in a html page. You must do something like this:

Winform

public Form1()
        {
            InitializeComponent();
            //navigate to you destination 
            webBrowser1.Navigate("https://www.certiport.com/portal/SSL/Login.aspx");
        }
        bool is_sec_page = false;
        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (!is_sec_page)
            {
                //get page element with id
                webBrowser1.Document.GetElementById("c_Username").InnerText = "username";
                webBrowser1.Document.GetElementById("c_Password").InnerText = "pass";
                //login in to account(fire a login button promagatelly)
                webBrowser1.Document.GetElementById("c_LoginBtn_c_CommandBtn").InvokeMember("click");
                is_sec_page = true;
            }
            //secound page(if correctly aotanticate
            else
            {
                //intract with sec page elements with theire ids and so on
            }

        }

Wpf

public MainWindow()
        {
            InitializeComponent();
     webBrowser1.Navigate(new Uri("https://www.certiport.com/portal/SSL/Login.aspx"));
            }
            bool is_sec_page = false;
            mshtml.HTMLDocument htmldoc;
            private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
            {
                htmldoc = webBrowser1.Document as mshtml.HTMLDocument;
                if (!is_sec_page)
                {
                    //get page element with id
                    htmldoc.getElementById("c_Username").innerText = "username";
                    //or
                    //htmldoc.getElementById("c_Username")..SetAttribute("value", "username");
                    htmldoc.getElementById("c_Password").innerText = "pass";
                    //login in to account(fire a login button promagatelly)
                    htmldoc.getElementById("c_LoginBtn_c_CommandBtn").InvokeMember("click");
                    is_sec_page = true;
                }
                //secound page(if correctly aotanticate
                else
                {
                    //intract with sec page elements with theire ids and so on
                }
            }

Just navigate to specific URL and fill page element.

Solution 2

If I understood you right you want to open some URL in web browser and then interact with site as a normal user would. For such task I can suggest taking look at Selenium. While it is typically used as a regression testing automation tool no one can stop you from using it as a browser automation tool.

Selenium has detailed documentation and big community. Most probably you will want to use Selenium WebDriver which is available via nuget.

Below is a little example of typical Selenium "script" (taken as-is from documentation):

// Create a new instance of the Firefox driver.

// Notice that the remainder of the code relies on the interface, 
// not the implementation.

// Further note that other drivers (InternetExplorerDriver,
// ChromeDriver, etc.) will require further configuration 
// before this example will work. See the wiki pages for the
// individual drivers at http://code.google.com/p/selenium/wiki
// for further information.
IWebDriver driver = new FirefoxDriver();

//Notice navigation is slightly different than the Java version
//This is because 'get' is a keyword in C#
driver.Navigate().GoToUrl("http://www.google.com/");

// Find the text input element by its name
IWebElement query = driver.FindElement(By.Name("q"));

// Enter something to search for
query.SendKeys("Cheese");

// Now submit the form. WebDriver will find the form for us from the element
query.Submit();

// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 10 seconds
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return d.Title.ToLower().StartsWith("cheese"); });

// Should see: "Cheese - Google Search"
System.Console.WriteLine("Page title is: " + driver.Title);

//Close the browser
driver.Quit();

Personally I can suggest to think and organize scripts in terms of user actions (register, login, fill form, select something in grid, filter grid, etc.). This will give a good shape and readability to scripts instead of messy hardcoded code chunks. The script in this case can look similar to this:

// Fill username and password
// Click on button "login"
// Wait until page got loaded
LoginAs("[email protected]", "johndoepasswd"); 

// Follow link in navigation menu
GotoPage(Pages.Reports); 

// Fill inputs to reflect year-to-date filter
// Click on filter button
// Wait until page refreshes
ReportsView.FilterBy(ReportsView.Filters.YTD(2012)); 

// Output value of Total row from grid
Console.WriteLine(ReportsView.Grid.Total);

Solution 3

if (webBrowser1.Document != null)
{
  HtmlElementCollection elems = webBrowser1.Document.GetElementsByTagName("input");
  foreach (HtmlElement elem in elems)
  {
    String nameStr = elem.GetAttribute("name");

    if (nameStr == "email")
    {
      webBrowser1.Document.GetElementById(nameStr).SetAttribute("value", "[email protected]");
    }
  }
}
Share:
50,749
Simon
Author by

Simon

Updated on July 05, 2022

Comments

  • Simon
    Simon almost 2 years

    We are currently investigating a method of creating a WPF/winforms application that we can set up internally to :-

    1. automatically open a new instance of a web browser to a predefined URL
    2. automatically complete required fields with predefined data
    3. automatically submit form and wait for the next page to load
    4. automatically complete required fields with predefined data (page 2)
    5. automatically submit form and wait for the next page to load (etc)

    after much investigation, the only thing we have managed to find is the opening up of a web browser via :-

    object o = null;
    
    SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer();
    IWebBrowserApp wb = (IWebBrowserApp)ie;
    wb.Visible = true;
    wb.Navigate(url, ref o, ref o, ref o, ref o);
    

    Any advice / reading recommendations would be appreciated on how to complete the process.

  • Simon
    Simon about 11 years
    Thank you for the quick response. however, this uses the built in browser control on a winform rather than opening up a new instance of a browser.. Is this the only way that this can be achieved (recommended way?)
  • KF2
    KF2 about 11 years
    @user2009091:you are using wpf?
  • Simon
    Simon about 11 years
    we can use either / or.. at the moment this is a proof of concept that we are trying to get working
  • Simon
    Simon about 11 years
    Thank you. However, this still relies on using the browser .net control.. And not actually opening up explorer.. Is this the only way to do this?
  • KF2
    KF2 about 11 years
    @user2009091:trye using SHDocVw.dll there is an article :codeproject.com/Articles/43491/…
  • Simon
    Simon about 11 years
    ah yes, this is what we where looking for.. and then implement the while (gmailurl.Busy) { System.Threading.Thread.Sleep(100); } to allow for the page to have completed before entering additional data. Do you recommend any additional reading material to complement this ?
  • KF2
    KF2 about 11 years
    @user2009091:i think this dll dose not contain any event for page load instead you can use a timer and check for one element in your form if exist page loaded completely(check as answer if my description help you:D)
  • B.K.
    B.K. about 10 years
    Brilliant! I've been looking for this type of solution for days.
  • GBK
    GBK about 10 years
    'mshtml.IHTMLElement' does not contain a definition for 'InvokeMember' and no extension method 'InvokeMember' accepting a first argument of type 'mshtml.IHTMLElement' could be found (are you missing a using directive or an assembly reference?
  • Yang Zhang
    Yang Zhang almost 9 years
    Great answer! Thank you!
  • Rafael
    Rafael about 7 years
    Hey @KF2, I like this answer, is there a way to approach this, in a similar way, using login tokens?