Use the mouse context menu to go Back/Forward in history navigation.

## Table of contents

1. Google search
2. User agent
3. Popups
4. HTML 5 video
5. Developer Tools
6. Downloads
7. HTML controls
8. Browser object
9. Frame object
10. Javascript bindings
11. Javascript callbacks
12. Python callbacks
13. Display handler
14. Keyboard handler
15. Request handler
16. Cookie tests
17. Load handler
18. Javascript Dialog handler
19. Other tests

## Google search

http://www.google.com/

## User agent

## Popups

1. window.open('wxpython.html')
2. target=_blank href="wxpython.html"
3. window.open('https://www.google.com/')

There are problems with keyboard when allow CEF to create popup windows internally. To create popup window explicitilly, the LifespanHandler::OnBeforePopup callback was implemented. See its source:

### CreateAnotherBrowser

This will create a window on its own and embed browser in it. When using "window.open" the window is created implicitilly by CEF. You can intercept such popup creation using the OnBeforePopup callback in LifespanHandler. You can return True in OnBeforePopup and create popup window on your own using the CreateAnotherBrowser function.
external.CreateAnotherBrowser()

## HTML5 video and accelerated content

HTML 5 video
Accelerated canvas
Accelerated layers

## Developer Tools

You can open devtools popup window in a few different ways:

1. Call Browser.ShowDevTools() method: external.ShowDevTools()
2. Through mouse context menu
3. Through F12 key which is handled in KeyboardHandler.OnKeyEvent

## Downloads

Download sample Ubuntu wallpapers:
https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip

Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED is called even for successful downloads, you can ignore this behavior. The proper console messages about successful/aborted download originate from C++ Browser process code, these are:

    Browser: About to download file: ubuntu-wallpapers2.zip
    Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip

If download was aborted the messages will be:

    Browser: About to download file: ubuntu-wallpapers2.zip
    Browser: Download was cancelled

Additionally on Linux there are more errors reported by Chromium about org.gnome.SessionManager.inhibit. These can be safely ignored as well.

A download handler with callbacks like `OnBeforeDownload` and `OnDownloadUpdated` may be exposed to CEF Python in the future.

## HTML controls

### Textarea

### Inputs

Text:
Password:

### Select

### Buttons

Submit:
Button:

## Browser object

Tests for the Browser object methods.

### GoBack

external.GoBack()

### GoForward

external.GoForward()

### LoadUrl, GetUrl

window.open('data:text/html,Test#Browser.LoadUrl')

### ReloadIgnoreCache, StopLoad

Press F5 to reload page and ignore cache.
Press Esc during webpage loading to abort.
Also, when Esc is pressed OnLoadError may get called. See how abort of page loading or file download is handled:

## Frame object

Tests for the Frame object methods. TODO.

## Javascript bindings

### PyPrint

window.PyPrint('printing in python console from js')

### Window properties

    jsBindings.SetProperty("pyProperty", "This was set in Python")
    jsBindings.SetProperty("pyConfig", ["This was set in Python",
            {"name": "Nested dictionary", "isNested": True},
            [1,"2", None]])

window.alert(window.pyProperty)
window.alert(JSON.stringify(window.pyConfig))

### Print

external.Print('printing again from js')

### TestAllTypes

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: [{}]}])

### ExecuteFunction

    <script>
    function JavascriptAlert(message) { window.alert(message); }
    </script>

external.ExecuteFunction('JavascriptAlert', 'python called from js and then js called from python')

### GetSource, GetText

external.GetSource()
external.GetText()

## Javascript callbacks

### TestJSCallback

    <script>
    function JSCallback(arg1) {
        window.alert(arg1)
    }
    </script>

external.TestJSCallback(JSCallback)

### TestJSCallbackComplexArguments

    <script>
    function JSCallback2() {
        window.alert(JSON.stringify(arguments))
    }
    </script>

external.TestJSCallbackComplexArguments({"myCallback": JSCallback2})

## Python callbacks

### TestPythonCallback

    <script>
    function JSCallback3(pyCallback) {
        pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
    }
    </script>

external.TestPythonCallback(JSCallback3)

## Display handler

### OnAddressChange

See messages in the console during loading of a webpage.

### OnTitleChange

See messages in the console during loading of a webpage.

### OnTooltip

See messages in the console when hovering over a google logo: http://www.google.com/

### OnStatusMessage

See messages in the console when hovering over links.

### OnConsoleMessage

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.

## Request handler

### OnBeforeResourceLoad

See messages in the console.

### OnResourceRedirect

Try this: http://tinyurl.com/google404redirect

### GetAuthCredentials

Try this: http://browserspy.dk/password-ok.php

### OnQuotaRequest

    <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

### OnProtocolExecution

Try magnet link to download a torrent: magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189

### _OnBeforePluginLoad

Try OnBeforePluginLoad() with Flash: http://www.adobe.com/software/flash/about/

### _OnCertificateError

The url below won't be allowed. Click twice "Back" from context menu to return back here after visiting that url:
https://testssl-expire.disig.sk/index.en.html
This url will be allowed:
https://testssl-expire.disig.sk/index.en.html?allow=1
After you've clicked the second url, the first one will now be allowed, as this is the same domain and it's cached now.

### OnRendererProcessTerminated

Try to terminate the "subprocess.exe" renderer process through task manager.

### OnPluginCrashed

No test for that yet.

## Cookie tests

See messages in the console.

### GetCookieManager

RequestHandler.GetCookieManager() - an example of having an unique cookie manager for each browser.

1. Visit the url below and set some cookies. Use "Back" from context menu to get back here (you might have to click "Back" multiple times).
   Visit it in the current browser:
   http://www.html-kit.com/tools/cookietester/
2. Open cookietester in a popup - a separate cookie manager is used:
   javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/')

Popup browsers created javascript's window.open share the same renderer process and request context. If you want to have separate cookie managers for popups created using window.open then you have to implement the LifespanHandler.`OnBeforePopup` callback. Return True in that callback to cancel popup creation and instead create the window on your own and embed browser in it. The CreateAnotherBrowser() function from the wxpython example does that.

### VisitAllCookies

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

### VisitUrlCookies

Visit a subset of cookies for the given url: external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/")

### SetCookie

Set a cookie on html-kit.com: external.SetCookie()
Go see the cookie that was created: http://www.html-kit.com/tools/cookietester/

### DeleteCookies

Delete the single cookie previously created via SetCookie(): external.DeleteCookies()
Go check if cookie was deleted: http://www.html-kit.com/tools/cookietester/

## Load Handler

See messages in the console during loading of a webpage.

### OnLoadingStateChange

### OnLoadStart

### OnLoadEnd

### OnLoadError

After you see the custom error message you have to hit twice the Back from the context menu, to get back to this page.
Try this: http://www.non-existent.nono/

## Javascript Dialog Handler

See messages in the console.

### OnJavascriptDialog

window.alert('Test js dialog handler')

### OnBeforeUnloadJavascriptDialog

    <script>
    function TestOnBeforeUnloadJavascriptDialog() {
        window.onbeforeunload = function() {
            return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
        }
        location.href = "wxpython.html";
    }
    </script>

TestOnBeforeUnloadJavascriptDialog()

### OnResetJavascriptDialogState

### OnJavascriptDialogClosed

## Other tests

### HTTPS caching with SSL certificate errors

Set ApplicationSettings["ignore_certificate_errors"] to True.

- https://192.168.0.17/test.html
- window.open('https://192.168.0.17/test.html')
- external.CreateAnotherBrowser('https://192.168.0.17/test.html')