blob: 1c2182714c505be1ff14c18e3e06be984287dc0e [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file declares the C++ side of PyAuto, the python interface to
// Chromium automation. It access Chromium's internals using Automation Proxy.
#ifndef CHROME_TEST_PYAUTOLIB_PYAUTOLIB_H_
#define CHROME_TEST_PYAUTOLIB_PYAUTOLIB_H_
#pragma once
#include "base/message_loop.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/test/test_timeouts.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/ui/ui_test_suite.h"
// The C++ style guide forbids using default arguments but I'm taking the
// liberty of allowing it in this file. The sole purpose of this (and the
// .cc) is to support the python interface, and default args are allowed in
// python. Strictly adhering to the guide here would mean having to re-define
// all methods in python just for the sake of providing default args. This
// seems cumbersome and unwanted.
// Test Suite for Pyauto tests. All one-time initializations go here.
class PyUITestSuiteBase : public UITestSuite {
public:
PyUITestSuiteBase(int argc, char** argv);
virtual ~PyUITestSuiteBase();
void InitializeWithPath(const FilePath& browser_dir);
void SetCrSourceRoot(const FilePath& path);
private:
base::mac::ScopedNSAutoreleasePool pool_;
};
// The primary class that interfaces with Automation Proxy.
// This class is accessed from python using swig.
class PyUITestBase : public UITestBase {
public:
// Only public methods are accessible from swig.
// Constructor. Lookup pyauto.py for doc on these args.
PyUITestBase(bool clear_profile, std::wstring homepage);
virtual ~PyUITestBase();
// Initialize the setup. Should be called before launching the browser.
// |browser_dir| is the path to dir containing chromium binaries.
void Initialize(const FilePath& browser_dir);
void UseNamedChannelID(const std::string& named_channel_id) {
named_channel_id_ = named_channel_id;
launcher_.reset(CreateProxyLauncher());
}
virtual ProxyLauncher* CreateProxyLauncher();
// SetUp,TearDown is redeclared as public to make it accessible from swig.
virtual void SetUp();
virtual void TearDown();
// Navigate to the given URL in the active tab. Blocks until page loaded.
void NavigateToURL(const char* url_string);
// Navigate to the given URL in the active tab in the given window.
void NavigateToURL(const char* url_string, int window_index);
// Navigate to the given URL in given tab in the given window.
// Blocks until page loaded.
void NavigateToURL(const char* url_string, int window_index, int tab_index);
// Reloads the active tab in the given window.
// Blocks until page reloaded.
void ReloadActiveTab(int window_index = 0);
// Get the URL of the active tab.
GURL GetActiveTabURL(int window_index = 0);
int GetTabCount(int window_index = 0);
// Appends a new tab with the given URL in the given or first browser window.
bool AppendTab(const GURL& tab_url, int window_index = 0);
// Activate the tab at the given zero-based index in the given or first
// browser window. Also brings the window to front.
bool ActivateTab(int tab_index, int window_index = 0);
// Apply the accelerator with given id (IDC_BACK, IDC_NEWTAB ...) to the
// browser window at the given or first index.
// The list can be found at chrome/app/chrome_command_ids.h
// Returns true if the call was successful.
bool ApplyAccelerator(int id, int window_index = 0);
// Like ApplyAccelerator except that it waits for the command to execute.
bool RunCommand(int browser_command, int window_index = 0);
// Shows or hides the download shelf.
void SetDownloadShelfVisible(bool is_visible, int window_index = 0);
// Determines the visibility of the download shelf
bool IsDownloadShelfVisible(int window_index = 0);
// Open the Find box
void OpenFindInPage(int window_index = 0);
// Determines the visibility of the Find box
bool IsFindInPageVisible(int window_index = 0);
// Get the path to the downloads directory
FilePath GetDownloadDirectory();
// AutomationProxy methods
// Open a new browser window. Returns false on failure.
bool OpenNewBrowserWindow(bool show);
// Close a browser window. Returns false on failure.
bool CloseBrowserWindow(int window_index);
// Fetch the number of browser windows. Includes popups.
int GetBrowserWindowCount();
// Installs the extension. Returns the extension ID only if the extension
// was installed and loaded successfully. Otherwise, returns the empty
// string. Overinstalls will fail.
std::string InstallExtension(const std::string& extension_path, bool with_ui);
// Returns bookmark bar visibility state.
bool GetBookmarkBarVisibility();
// Returns bookmark bar animation state. Warning: timing issues may
// change this return value unexpectedly.
bool IsBookmarkBarAnimating();
// Wait for the bookmark bar animation to complete.
// If |wait_for_open| is true, wait for it to open.
// If |wait_for_open| is false, wait for it to close.
bool WaitForBookmarkBarVisibilityChange(bool wait_for_open);
// Get the bookmarks as a JSON string. Internal method.
std::string _GetBookmarksAsJSON();
// Editing of the bookmark model. Bookmarks are referenced by id.
// The id is a std::wstring, not an int64, for convenience, since
// the python side gets IDs converted from a JSON representation
// (which "extracts" into a string, not an int). Since IDs are
// grabbed from the current model (and not generated), a conversion
// is unnecessary. URLs are strings and not GURLs for a similar reason.
// Bookmark or group (folder) creation:
bool AddBookmarkGroup(std::wstring& parent_id, int index,
std::wstring& title);
bool AddBookmarkURL(std::wstring& parent_id, int index,
std::wstring& title, std::wstring& url);
// Bookmark editing:
bool ReparentBookmark(std::wstring& id, std::wstring& new_parent_id,
int index);
bool SetBookmarkTitle(std::wstring& id, std::wstring& title);
bool SetBookmarkURL(std::wstring& id, std::wstring& url);
// Finally, bookmark deletion:
bool RemoveBookmark(std::wstring& id);
// Get a handle to browser window at the given index, or NULL on failure.
scoped_refptr<BrowserProxy> GetBrowserWindow(int window_index);
// Meta-methods. Generic pattern of passing args and response as
// JSON dict to avoid future use of the SWIG interface and
// automation proxy additions. Returns response as JSON dict.
// Use -ve window_index for automation calls not targetted at a browser
// window. Example: Login call for chromeos.
std::string _SendJSONRequest(int window_index,
const std::string& request,
int timeout);
// Execute javascript in a given tab, and return the response. This is
// a low-level method intended for use mostly by GetDOMValue(). Note that
// any complicated manipulation of the page should be done by something
// like WebDriver, not PyAuto. Also note that in order for the script to
// return a value to the calling code, it invokes
// window.domAutomationController.send(), passing in the intended return
// value.
std::wstring ExecuteJavascript(const std::wstring& script,
int window_index = 0,
int tab_index = 0,
const std::wstring& frame_xpath = L"");
// Evaluate a Javascript expression and return the result as a string. This
// method is intended largely to read values out of the frame DOM.
std::wstring GetDOMValue(const std::wstring& expr,
int window_index = 0,
int tab_index = 0,
const std::wstring& frame_xpath = L"");
// Resets to the default theme. Returns true on success.
bool ResetToDefaultTheme();
// Sets a cookie value for a url. Returns true on success.
bool SetCookie(const GURL& cookie_url, const std::string& value,
int window_index = 0, int tab_index = 0);
// Gets a cookie value for the given url.
std::string GetCookie(const GURL& cookie_url, int window_index = 0,
int tab_index = 0);
int action_max_timeout_ms() const {
return TestTimeouts::action_max_timeout_ms();
}
int large_test_timeout_ms() const {
return TestTimeouts::large_test_timeout_ms();
}
private:
// Enables PostTask to main thread.
// Should be shared across multiple instances of PyUITestBase so that this
// class is re-entrant and multiple instances can be created.
// This is necessary since python's unittest module creates instances of
// TestCase at load time itself.
static MessageLoop* GetSharedMessageLoop(MessageLoop::Type msg_loop_type);
static MessageLoop* message_loop_;
// Path to named channel id.
std::string named_channel_id_;
};
#endif // CHROME_TEST_PYAUTOLIB_PYAUTOLIB_H_