Links

http://www.google.com/ http://en.wikipedia.org/

UTF-8

Plain: ąśö
HTML: €ö

User agent

Popup

window.open('http://www.google.com')

Select Tag



Input Tag

Your name:
Please send me spam about everything
You are: male female

TextArea Tag

HTML5 video and accelerated content

HTML 5 video
Accelerated canvas
Accelerated layers

Javascript dialogs

alert('test (utf-8: ąśö)')
confirm('test (utf-8: ąśö)')
cprompt('test (utf-8: ąśö)', 'test (utf-8: ąśö)')

External

Javascript bindings

PyPrint('printing in python console from js')
window.alert(window.pyProperty)
window.alert(JSON.stringify(window.pyConfig))
external.Print('printing again from js')
external.TestAllTypes (undefined, null, true, 1, ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}])
<script>
function JavascriptAlert(message) { window.alert(message); }
</script>
external.ExecuteFunction('JavascriptAlert', 'python called from js and then js called from python')

GetSource() to console
GetText() to console

Javascript callbacks

<script>
function JSCallback(arg1) {
    window.alert(arg1)
}
</script>
def TestJSCallback(self, jsCallback):
    print("jsCallback.GetFunctionName() = %s" % jsCallback.GetFunctionName())
    print("jsCallback.GetFrame().GetIdentifier() = %s" % \
            jsCallback.GetFrame().GetIdentifier())
    jsCallback.Call("This message was sent from python using js callback")
external.TestJSCallback(JSCallback)
<script>
function JSCallback2() {
    window.alert(JSON.stringify(arguments))
}
</script>
def TestJSCallbackComplexArguments(self, jsObject):
    jsCallback = jsObject["myCallback"];
    jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \
            {"nested object":None}]], \
            {"nested list next":[{"deeply nested object":1}]})
external.TestJSCallbackComplexArguments({"myCallback": JSCallback2})

Python callbacks

<script>
function JSCallback3(pyCallback) {
    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
}
</script>
def TestPythonCallback(self, jsCallback):
    jsCallback.Call(PyCallback)

def PyCallback(self, *args):
        message = "PyCallback() was executed successfully! Arguments: %s" \
                % str(args)
        print(message)
        self.mainBrowser.GetMainFrame().ExecuteJavascript(
                "window.alert(\"%s\")" % message)
external.TestPythonCallback(JSCallback3)

Display handler

def OnLoadingStateChange(self, browser, isLoading, canGoBack, 
        canGoForward):
    print("ClientHandler::OnLoadingStateChange()")
    print("isLoading = %s, canGoBack = %s, canGoForward = %s" \
            % (isLoading, canGoBack, canGoForward))
See messages in the console during loading of a webpage.
def OnAddressChange(self, browser, frame, url):
    print("ClientHandler::OnAddressChange()")
    print("url = %s" % url)
See messages in the console during loading of a webpage.
def OnTitleChange(self, browser, title):
    print("ClientHandler::OnTitleChange()")
    print("title = %s" % title)
See messages in the console during loading of a webpage.
def OnTooltip(self, browser, textOut):
    # OnTooltip not yet implemented (both Linux and Windows), 
    # will be fixed in next CEF release, see Issue 783:
    # https://code.google.com/p/chromiumembedded/issues/detail?id=783
    print("DisplayHandler::OnTooltip()")
    print("text = %s" % textOut[0])
See messages in the console when hovering over a google logo: http://www.google.com/
def OnStatusMessage(self, browser, value):
    if not value:
        # Do not notify in the console about empty statuses.
        return
    self.statusMessageCount += 1
    if self.statusMessageCount > 3:
        # Do not spam too much.
        return
    print("DisplayHandler::OnStatusMessage()")
    print("value = %s" % value)
See messages in the console when hovering over links.
def OnConsoleMessage(self, browser, message, source, line):
    print("ClientHandler::OnConsoleMessage()")
    print("message = %s" % message)
    print("source = %s" % source)
    print("line = %s" % line)
Try this: http://patik.com/code/console-log-polyfill/

Keyboard handler

Press F5 to reload the page.
On Linux it is required to click anywhere in the window first so that keyboard focus is set. See Issue 77 in the CEF Python Issue Tracker.

def OnPreKeyEvent(self, browser, event, eventHandle, 
        isKeyboardShortcutOut):
    print("ClientHandler::OnPreKeyEvent()")

def OnKeyEvent(self, browser, event, eventHandle):
    print("ClientHandler::OnKeyEvent()")
    print("native_key_code = %s" % event["native_key_code"])
    if platform.system() == "Linux":
        # F5 = 71
        if event["native_key_code"] == 71:
            print("F5 pressed! Reloading page..")
            browser.ReloadIgnoreCache()

Request handler

def OnBeforeResourceLoad(self, browser, frame, request):
    print("RequestHandler::OnBeforeResourceLoad()")
    print("url = %s" % request.GetUrl()[:70])
    return False
See messages in the console.
def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut):
    print("RequestHandler::OnResourceRedirect()")
    print("old url = %s" % oldUrl[:70])
    print("new url = %s" % newUrlOut[0][:70])
Try this: http://tinyurl.com/google404redirect
def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm,
        scheme, callback):
    print("RequestHandler::GetAuthCredentials()")
    print("host = %s" % host)
    print("realm = %s" % realm)
    callback.Continue(username="test", password="test")
    return True
Try this: http://browserspy.dk/password-ok.php
def OnQuotaRequest(self, browser, originUrl, newSize, callback):
    print("RequestHandler::OnQuotaRequest()")
    print("origin url = %s" % originUrl)
    print("new size = %s" % newSize)
    callback.Continue(True)
    return True
<script>
function DoRequestQuota() {
    // Request Quota (only for File System API)  
    try {
        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
                function(bytes){ window.alert("Granted bytes: "+bytes);},
                function(error){ window.alert(error); });
    } catch(e) {
        navigator.webkitPersistentStorage.requestQuota(1024*1024,
                function(bytes){ window.alert("Granted bytes: "+bytes);},
                function(error){ window.alert(error); });
    }
}
</script>
Try this: https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html
def OnProtocolExecution(self, browser, url, allowExecutionOut):
    # There's no default implementation for OnProtocolExecution on Linux,
    # you have to make OS system call on your own. You probably also need
    # to use LoadHandler::OnLoadError() when implementing this on Linux.
    print("RequestHandler::OnProtocolExecution()")
    print("url = %s" % url)
    if url.startswith("magnet:"):
        print("Magnet link allowed!")
        allowExecutionOut[0] = True
Try this: magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189
def _OnBeforePluginLoad(self, browser, url, policyUrl, info):
    # Plugins are loaded on demand, only when website requires it,
    # the same plugin may be called multiple times.
    print("RequestHandler::OnBeforePluginLoad()")
    print("url = %s" % url)
    print("policy url = %s" % policyUrl)
    print("info.GetName() = %s" % info.GetName())
    print("info.GetPath() = %s" % info.GetPath())
    print("info.GetVersion() = %s" % info.GetVersion())
    print("info.GetDescription() = %s" % info.GetDescription())
    # False to allow, True to block plugin.
    return False
Try OnBeforePluginLoad() with Flash: http://www.adobe.com/software/flash/about/
def _OnCertificateError(self, certError, requestUrl, callback):
    print("RequestHandler::OnCertificateError()")
    print("certError = %s" % certError)
    print("requestUrl = %s" % requestUrl)
    if requestUrl.startswith(
            "https://sage.math.washington.edu:8091/do-not-allow"):
        print("Not allowed!")
        return False
    if requestUrl.startswith(
            "https://sage.math.washington.edu:8091/hudson/job/"):
        print("Allowed!")
        callback.Continue(True)
        return True
    return False
This won't be allowed: https://sage.math.washington.edu:8091/do-not-allow
This will be allowed: https://sage.math.washington.edu:8091/hudson/job/cython-docs/

Cookie tests

See messages in the console.
 def GetCookieManager(self, browser, mainUrl):
    # Create unique cookie manager for each browser.
    # --
    # Buggy implementation in CEF, reported here:
    # https://code.google.com/p/chromiumembedded/issues/detail?id=1043
    cookieManager = browser.GetUserData("cookieManager")
    if cookieManager:
        return cookieManager
    else:
        cookieManager = cefpython.CookieManager.CreateManager("")
        browser.SetUserData("cookieManager", cookieManager)
        return cookieManager
RequestHandler.GetCookieManager() - an example of having an unique cookie manager for each browser. Visit http://www.html-kit.com/tools/cookietester/ and set some cookie, then go back to this page using the context menu and open a new popup window, the cookie should not appear in the popup browser window.

CookieManager.VisitAllCookies() - visit all cookies: external.VisitAllCookies() (note: visit some http:// webpage first, otherwise cookie manager is not yet created)

CookieManager.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") - visit a subset of cookies given the url, test: external.VisitUrlCookies()

CookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", {name:"Created_Via_Python", value:"yeah really"}) - create the cookie: external.SetCookie()

CookieManager.DeleteCookies() - delete the single cookie previously created via SetCookie(): external.DeleteCookies()

Load Handler

def OnLoadStart(self, browser, frame):
    print("LoadHandler::OnLoadStart()")
    print("frame url = %s" % frame.GetUrl()[:70])
See messages in the console.
def OnLoadEnd(self, browser, frame, httpStatusCode):
    print("LoadHandler::OnLoadEnd()")
    print("frame url = %s" % frame.GetUrl()[:70])
    # For file:// urls the status code = 0
    print("http status code = %s" % httpStatusCode)
See messages in the console.
def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl):
    print("LoadHandler::OnLoadError()")
    print("frame url = %s" % frame.GetUrl()[:70])
    print("error code = %s" % errorCode)
    print("error text = %s" % errorTextList[0])
    print("failed url = %s" % failedUrl)
    customErrorMessage = "My custom error message!"
    frame.LoadUrl("data:text/html,%s" % customErrorMessage)
Try this: http://www.non-existent.nono/
(After you see the custom error message you have to hit twice the Back from the context menu, to get back to this page)
def OnRendererProcessTerminated(self, browser, status):
    print("LoadHandler::OnRendererProcessTerminated()")
    statuses = {
        cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION",
        cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED",
        cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED"
    }
    statusName = "Unknown"
    if status in statuses:
        statusName = statuses[status]
    print("status = %s" % statusName)
Try to terminate the "subprocess.exe" renderer process through process/task manager.
def OnPluginCrashed(self, browser, pluginPath):
    print("LoadHandler::OnPluginCrashed()")
    print("plugin path = %s" % pluginPath)
No test for that yet.

Other tests