Cocoa automated WebView - objective-c

I looking into making a kind of robot testing browser. Like Selenium, but one that we can use to make full integration tests of our site. I'm wondering if it's possible to create a Cocoa app that loads up a web page in a WebView and they programmatically sends click events. I realize you could use:
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
To send js click evenets, but it would be better if you could send click events to the DOMElements themselves. That way you could test file uploads and other elements that can't be accessed via javascript like flash. Does anyone know if this is possible?

You can obtain DOMNode* objects corresponding exactly to JavaScript Node objects by using a WebView's -windowScriptObject method (that returns the WebScriptingObject* that corresponds to the JavaScript window object) or any frame's -DOMDocument method to return that frame's JavaScript document method.
Example:
DOMDocument* d = [[webView mainFrame] DOMDocument];
[[[d getElementsByTagName:#"a"] item:0] click];

Fake sounds like exactly what you want. It's WebKit based, automated, has tab support, and a huge library full of useful things like evaluating JavaScript, assertions, variables, events, and loops. Highly recommended.

Related

Make input in program input value at website

I want a function in my JavaFX 2.0 program that takes user input and forwards it to a websites textfield, and then get the value the website returns. The website would be a site to check if the warranty for a spesific program is valid.
All the user would need to input is reg. ID and maybe program brand.
I'm just looking for ideas on how to do this, links or even code would be superb. I suspect it won't require that much code, but hey.. i've been surprised before!
Thanks! :)
A possible implementation algorithm:
Load the warranty check page in the WebView.
Monitor the webEngine.documentProperty to check for when the load has finished.
When the load has finished, use webEngine.executeScript to set the text field to the
required value and submit the form.
EITHER
a. monitor the webEngine.documentProperty some more, and, when the document has loaded, inspect the document (using either JavaScript or Java) to see if the warranty is valid.
OR
b. change the resultant warranty display page to call back into Java and notify your app of the warranty status.
Some background info
If you have control over the website page contents, then your implementation may turn out easier. But I think you should still be able to get the result you want without modifying the website.
There were some additions to the recent JavaFX 2.1 release to facilitate callbacks from Javascript to Java. The webview documentation you want to read is the sections "Processing JavaScript Commands" using the webEngine.executeScript method and "Making Upcalls from JavaScript to JavaFX" using JSObject.setMember.
You might want to also take a look at a Sample DatePicker for JavaFX using jQuery UI example I wrote. It demonstrates various methods for loading html into a WebView, invoking functions on the WebView from Java and getting the results of user interactions with the WebView back into Java. Not exactly what you are looking for, but perhaps the ideas in it may help.
Another option you have is just to:
Accept the registration id in a JavaFX control.
Create a java.net.URL and post to the webserver from your java app directly without using a WebView.
Parse the response from the webserver to extract out whether the warranty is valid.
This is the approach I might take for such a task - eliminating the use of WebView completely.

Apple Mail and its Webview Component

Does anyone know what Apple Mail is written in?
I'm trying to determine what component it uses to render HTML, is it using the Webview Class?
Are there any other options to render HTML when building OS X applications?
It's an Objective-C/Cocoa app and it's using WebView.
I know secondhand (from a developer who was tracking down bugs in his app and comparing behavior to Mail) it takes advantage of some undocumented calls to accomplish certain things. But for the most part it's the same WebView that you've got access to.
If you'd rather render HTML a different way, you could check out Gecko, the engine/library that Firefox and Camino are based on.

How to simulate a click in a webpage in iOS with objective-C

I'm looking for an equivalent of Mechanize (Ruby/python and more) for iOS.
I need to simulate a click in a webpage (form submission) and get the response back. I tried to construct a POST-request using ASIHTTPRequest without succes. I was able to create a solution in Ruby (with Mechanize) but I want to be able to do the same in objective-c for iphone development. Any suggestions ?
As described in the duplicated posts, the API to programmatically simulate touches is private, so not appropriate for a shipping app. Follow the links if you want to know how to do it anyway.

Getting DOM from page using Chromium/WebKit

Trying to get access to a page's DOM after rendering. I do not need to view the page and plan to apply this programmatically without any GUI or interaction.
The reason I am interested in post-rendering is that I want to know where objects appear. Some location information is coded in the HTML (e.g., via offsetLeft), but much is not. Also, Javascript can change the ultimate positioning. I want positions that are as close to what the user will see as possible.
I've looked into Chromium code and think there is a way to do this but there is not enough documentation to get started.
Putting it VERY simply I'd be interested in pseudo-code like this:
DOMRoot *r = new Page("http://stackoverflow.com")->getDom();
Any tips on starting points?
You should use the Web API wrapper that Chromium exposes; specifically, the WebDocument class contains the functionality that you need. You can call it like this:
WebFrame * mainFrame = webView->mainFrame();
WebDocument document = mainFrame->document();
WebElement docElement = document->docElement();
// Manipulate the DOM here using docElement
...
You can browse the source code for Chromium's Web API wrapper here. Although there's not much in the way of documentation, the header files are fairly well-commented and you can browse Chrome's source code to see the API in action.
It's difficult to get started using Chromium. I recommend looking at the test_shell application. Also, a framework like the Chromium Embedded Framework (CEF) simplifies the process of embedding Chromium in your application; I use CEF in my current project and I'm very satisfied with it.

How can I expose an Objective-C function to JavaScript using WebKit on Mac OS X?

I understand to do this on the iPhone you need to trap link requests (as per my other iPhone question UIWebView Expose JavaScript) and you can easily do the reverse and access JavaScript from Obj-C code.
However, I would like to have JavaScript be able to call some Objective-C functions that would somehow be registered with WebKit. I assume that you can do this better than trapping links like on the iPhone as on Mac OS X we have access to the full WebKit.
I wish to basically do the reverse of Using JavaScript from Objective-C
Update: For example is it possible to expose the objective-c method in JavaScript like self.external.objcmethod();
Have a look at my answer to this question, which is very similar. I provide code that shows you exactly how to do what you want.
Essentially, you need to implement the WebScripting protocol as per the documentation.
You don't need to define your own URL scheme handler, that is only necessary for iPhone applications. On the Mac the WebView object is many orders of magnitude more powerful than UIWebView on the iPhone and allows full bridging from JavaScript to Objective-C and vice versa.
You can browse to "javascript:my_method()" and intercept the loading...
Look at UIWebViewDelegate delegate.
Documentation at http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIWebViewDelegate_Protocol/Reference/Reference.html
Look at the method shouldStartLoadWithRequest
((BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType)
Addtionally, you may want to look at https://dev.mobileread.com/trac/webkitbrowser/browser/trunk/WebKit-r30377/WebKit/qt/Api/qwebframe.cpp#L167
The way I've done this in the past is to implement my own URL scheme. In your HTML pages, you'd create links like myapp://dosomefunction?aParameter=aValue. Mac OS X will open your application (if it's not already running) and pass it the URL when you click these links. It's slightly more convenient than trapping requests, and it would work with any web view anywhere on the system.
See the accepted answer to this question for details on how to set up the handler. Unfortunately, this is a one-way operation. You won't be able to get any return values back from the application.