Exposing WebKit internals for layout tests:
This turned out to be a bit harder than one might expect. Many methods of the Document object are already public, but not all the ones that we might need. In my case, I needed a way to get at the list of favicon URLs in the head of the document. My plan was to do something similar to what DumpRenderTree does, and dump out the icon url list in the Layout Test, then check that the dumped text matched the expected dumped text.
The approach that didn’t pass CR: (in case you need to try something similar someday)
My first thought was to try and expose the methods so that I could call them from the dump render tree code, which is easy enough. I put them into Document.h, but Document.h is not exposed to external callers. To be exposed to clients of WebKit, you need to expose the function in WebDocument.h (and WebFrame.h, in this case). WebFrame and WebDocument have access to the internals of Frame and Document, and can copy items from the Frame and Document into their own internal data structures and expose them. You have to build the C++ to back the JS methods in LayoutTexstController.cpp After that, I was able to write a DumpRenderTree function in TestShell.cpp to dump the icon URL list.
However, that involved modifying the public API of webkit to make available the icon URL list. When the code got to code review, the approach was rejected. (The same approach might still work for you if your case does not require adding new methods to the WebKit API, which is why I’ve documented it here.)
The internals approach:
A second approach is to use the “Internals” object, which exists for this purpose. Any newer stuff you want to expose from the internals of webkit to layout tests should be put here. With this approach, I was able to expose a list of icon URLs to a JavaScript function running in the layout tests.
Here’s what you need to do (you can look at my change in webkit bug 88665 for an example).
- In Internals.cpp, I made a new function to return the data I needed. I copied the list from the Document class into a DOMStringList. This let me expose it to JavaScript as a return value.
- To generate a tie between Internals.cpp and the exposed JavaScript, I added the corresponding function in “internals.idl”. (If you are an old school Windows programmer new to WebKit, note that this is WebKit idl, don’t confuse it with the idl used for RPC).
- Internals needed the functions that it calls in the document object to be exported so it can find them. This means modifying Source/WebCore/WebCore.exp.in (for Mac), Source/WebKit2/win/WebKit2.def (for Windows), and Source/autotools/symbols.filter (for GTK+). It needs a c++ decorated name for that platform. The decorated name for the Mac and GTK+ look similar (one less leading underscore, otherwise the same). Note that symbols.filter ends with a semicolon, and the others do not. The files are sorted, so maintain the sort order when you add your symbol.
- In the javascript of the layout test, I call the new method as “window.internals.my-method(). I was able to check in JS that the data returned matched what the test expected, and print PASS or FAIL into the results.