Using class WebBrowser to open IE and fetch HtmlElement - c#

I'm using Microsoft Visual Studio 2013 Ultimate and am currently using a Coded UI Test Project. When using it for a Console application, I get the error "An unhandled exception of type 'System.Threading.ThreadStateException' occurred in System.Windows.Forms.dll" when executing the first line of code below, but I don't get it when using my coded UI test project.
The end intention of my code is to launch a web browser. Click some links, and read information from certain ID fields from within the browser. If someone knows of a better or simply working implementation of doing that, I am all for it.
In my current implementation, internet explorer is never launched.
WebBrowser web = new WebBrowser(); //create object web browser
web.CreateControl();
web.Visible = true;
web.ScriptErrorsSuppressed = true;
web.Navigate("www.gogle.com"); //Shouldn't this launch IE & go to google.com?
HtmlDocument doc = web.Document;
HtmlElement el = doc.GetElementById("hplogo");//get htmlelement on the google logo
//do something with info from el.
web.Dispose(); //de-allocate

From MS KB841295 you can add the STAThread() attribute to your main entry point of your program and this should resolve that specific exception.
[STAThread()]
static void Main(string[] args) {
WebBrowser web = new WebBrowser(); //create object web browser
//...
}

Related

scraping website that is generated by javascript in C#

I am new to coding. I am trying to make a simple console app that will run internet speed test. I've searched all over and I couldn't find the answer. I tried all the sample answers but I couldn't get the program to run. For now, my program returns 0 which is a value from HTML source document. I need the value from javascript. the website is https://fast.com/en/ I only need the speed test results. I need help. here is my code:
enter code here
class Program
{
[STAThread]
static void Main(string[] args)
{
HtmlWeb web = new HtmlWeb();
string url = "https://fast.com/en/";
HtmlDocument doc = web.LoadFromBrowser(url, html =>
{
return !html.Contains
("<div class=\"speed-results-container succeeded\"
id=\"speed_value\" ></div>");
});
var t1 = doc.DocumentNode.SelectSingleNode
("//div[#id='speed-value']").InnerText;
Console.WriteLine($"{t1}");
}
}
So the whole "magic" of the test is made in app-ea56f7.js file.
This file is sending request and receiving chunks of data from netflix. Unfortunately, as referenced in Running Scripts in HtmlAgilityPack there is no direct way of having this without using a headless browser.
Either use https://www.npmjs.com/package/speedtest-net

TypeLoadException for 'OpenQA.Selenium.Support.UI.WebDriverWait' when trying to run selenium test

I'm getting the following error when trying to run my selenium webdriver tests from a user control I have created:
An exception of type 'System.TypeLoadException' occurred in UserCreationFrontEnd.exe but was not handled in user code
Additional information: Could not load type 'OpenQA.Selenium.Support.UI.WebDriverWait' from assembly 'WebDriver, Version=2.48.2.0, Culture=neutral, PublicKeyToken=null'.
Background story: I have created an app with some automated test suites in that allows people within my team without visual studio to run them. This app is a winforms app and is written in c# and uses user controls. I have added a user control into my selenium solution to run the selenium tests. When I run the user control from here the tests run as expected.
The issue appears when I add the user control into my main application and try and run the selenium tests from there.
The user control is displayed fine, but when I try to start the tests I get the error in my test start up (OneTimeSetUp).
Code:
public void TestStartUp()
{
driver = new InternetExplorerDriver(#"O:\Testing\SDET\SeleniumWebDriver");
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
config = new MapsPageObjectModel.EnvironmentConfig(driver);
navBar = new MapsPageObjectModel.NavigationBar(driver);
homePage = new MapsPageObjectModel.Homepage(driver);
createContact = new MapsPageObjectModel.CreateContact(driver);
securityManager = new MapsPageObjectModel.SecurityManager(driver);
companyPage = new MapsPageObjectModel.Company(driver);
createEmployee = new MapsPageObjectModel.CreateEmployee(driver);
roles = new MapsPageObjectModel.Roles(driver);
UserCreationResults.Clear();
}
The error happens on this line
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
Does anyone have any idea's?
Go to Manage NuGet window and make sure you have installed same version of Selenium.Support and Selenium.WebDriver across all your projects in your solution.
You need to have both usings in your .cs file:
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
Also u need to have refences to WebDriver and WebDriver.Support.

Unable to find an element in Browser of the Android emulator using Appium and C#

I want to automate mobile web site testing on Android emulator using c# and Appium. There is a simple test scenario I want to automate for the start:
1. Start Browser
2. Find an element
3. Clear it
4. Send keys
I've got a problem with the second step. Every time MSTest tries to execute FindElementById line in the code below, I get the error:
"An element could not be located on the page using the given search parameters."
[TestClass]
public class UnitTest1
{
private DesiredCapabilities _capabilities;
private AndroidDriver _driver;
public void InitializeDriver()
{
Console.WriteLine("Connecting to Appium server");
_capabilities = new DesiredCapabilities();
_capabilities.SetCapability("deviceName", "test_02");
_capabilities.SetCapability(CapabilityType.BrowserName, "Chrome");
_capabilities.SetCapability(CapabilityType.Version, "5.0.1");
_capabilities.SetCapability(CapabilityType.Platform, "Android");
//Application path and configurations
_driver = new AndroidDriver(new Uri("http://127.0.0.1:4723/wd/hub"), _capabilities);
}
[TestMethod]
public void TestMethod1()
{
InitializeDriver();
var element = _driver.FindElementById("com.android.browser:id/url");
element.Clear();
element.SendKeys(#"http://stackoverflow.com/");
}
}
Input string for the method I've got from UIAutomator that is shown below.
I tried several combinations for the FindElementById input method:
"com.android.browser:id/url"
"id/url"
"url"
but no luck.
My environment:
Windows 8.1
Appium 1.3.4.1
ChromeDriver 2.14.313457
Android Device Monitor 24.0.2
Sorry for misleading !!!
In case of testing web apps in browser the elements should be located as usual elements on the web page ( not as some classes like android.widget.EditText and android.widget.Button). So try for example the following and you will see some result:
var element = _driver
.findElementByXPath("//input[#id='lst-ib']");
To get locators you should run the browser on your desktop, open the page and use some tools/extensions like Firebug in Firefox or Firebug Lite in Chrome browser.
Try these 2 statements:
var element = _driver.FindElement(By.Id("com.android.browser:id/url");
driver.findElementsByXPath("//*[#class='com.android.browser' and #index='1']");
Update ! The following approach is not for web testing:
Could you try to find the element using xpath?
#FindBy(xpath="//android.widget.EditText[contains(#resource-id, 'url')]")
So in your case you can try the following:
var element = _driver.findElementByXPath("//android.widget.EditText[contains(#resource-id, 'url')]");
Update: in case of testing web apps (not native) you should use web page locators instead of Android classes.

How to pass data from windows application to web application?

I have a windows application and i want to open my web application from this windows application. My Windows application will generate a key and machine code after authorization and will save the key and machine code in to database among active users. Now i want to send this key to browser so that my web application can identify the user with his machine.
How can i do this?
i cannot use URL because the user will be able to copy the URL and use my web application from another machine. I must restrict it.
Is there any other way?
There are Two Ways to transfer winform data to web applications
If you want to transfer the data to IE then You can Use
1)MSHtml.dll
code
InternetExplorer TargetIE = null;
IHTMLDocument2 document = null;
//Check whether the IE is opened
foreach (InternetExplorer internetExplorer in new ShellWindows())
{
if (internetExplorer.Document is HTMLDocument)
{
TargetIE = internetExplorer;
break;
}
}
2) If you want to transfer data from winform to any web browser my personal advice to you please use selenium for this.
download the respective dll and driver for respective drivers from this site help
Code
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Chrome;
namespace WindowsFormsChrome
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// download the chrome driver
IWebDriver driver = new ChromeDriver(#"C:\Users\Downloads\chromedriver");
driver.Navigate().GoToUrl("http://www.yahoo.com");
IWebElement myField = driver.FindElement(By.Id("txtUserName"));
myField.SendKeys("UserName");
IWebElement myField = driver.FindElement(By.Id("txtPassword"));
myField.SendKeys("Password");
IWebElement myField = driver.FindElement(By.Id("btnLogin"));
myField.click()
}
}
}
this second part work for all browser yoou just replace chromeDriver class as per you want.
you can POST data using c#
http://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx
see also this post in stackoverflow
How to post data to a website
You can write an ashx handler and pass your data (or some reference to your data) from your windows application. Here is an example how this can be done :
how to call ASHX handler and getting the result back

BHO Plugin (Microsoft JScript runtime error)

I have built a BHO (Browser Helper Object) in C# which detects phone numbers in web pages and places an image with a hyperlink next to it. The BHO basically inserts a javascript which uses a Regex String to find phone numbers and adds the image next to it.
This is the relevant code
public void OnDocumentComplete(object pDisp, ref object URL)
{
HTMLDocument document = (HTMLDocument)webBrowser.Document;
IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)
document.all.tags("head")).item(null, 0);
IHTMLScriptElement scriptObject =
(IHTMLScriptElement)document.createElement("script");
scriptObject.src = "\nhttp://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js";
((HTMLHeadElement)head).appendChild((IHTMLDOMNode)scriptObject);
IHTMLScriptElement scriptObject2 =
(IHTMLScriptElement)document.createElement("script");
scriptObject2.text = "\nwindow.onload = function()"+
"{"+
"$('body').html( $('body').html().replace(/(\\d\\d\\d\\d\\s\\d\\d\\d\\s\\d\\d\\d)/g,'$1 <img src=\"image.png\" border=\"0\">') );"
+"}"+
"\n\n";
((HTMLHeadElement)head).appendChild((IHTMLDOMNode)scriptObject2);
}
I have tested the BHO in IE on a very simple page with few phone numbers. It works as expected. But when i test the BHO with any other page on the web i get the following error
Microsoft JScript runtime error: Object doesn't support this property or method
or
Microsoft JScript runtime error: Permission denied
I am getting Microsoft JScript runtime error for a few other pages. Does this mean that i am not allowed to insert a javascript into the page ? What could be the reason ? I hope this is the right way to do it.
I think the errors are thrown because you add jQuery multiple times to the site you're loading. Have you ever tried to set a breakpoint inside the OnDocumentComplete method?
If you do so, you will see, that the OnDocumentComplete event is fired more than one time, per site request.
So you should check at first, if it's the first time the OnDocumentComplete event is fired for the actual site request. If so, add you javascript, if not, do nothing.
This should prevent double jQuery includes.

Categories

Resources