Merge pull request #652 from atom/chromedriver
Ship chromedriver and add docs on how to use it
This commit is contained in:
commit
1381d16f9c
11 changed files with 160 additions and 6 deletions
30
atom.gyp
30
atom.gyp
|
@ -688,6 +688,36 @@
|
||||||
}], # OS=="linux"
|
}], # OS=="linux"
|
||||||
],
|
],
|
||||||
}, # target <(project_name>_dump_symbols
|
}, # target <(project_name>_dump_symbols
|
||||||
|
{
|
||||||
|
'target_name': 'copy_chromedriver',
|
||||||
|
'type': 'none',
|
||||||
|
'actions': [
|
||||||
|
{
|
||||||
|
'action_name': 'Copy ChromeDriver Binary',
|
||||||
|
'variables': {
|
||||||
|
'conditions': [
|
||||||
|
['OS=="win"', {
|
||||||
|
'chromedriver_binary': 'chromedriver.exe',
|
||||||
|
},{
|
||||||
|
'chromedriver_binary': 'chromedriver',
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'inputs': [
|
||||||
|
'<(libchromiumcontent_library_dir)/<(chromedriver_binary)',
|
||||||
|
],
|
||||||
|
'outputs': [
|
||||||
|
'<(PRODUCT_DIR)/<(chromedriver_binary)',
|
||||||
|
],
|
||||||
|
'action': [
|
||||||
|
'python',
|
||||||
|
'tools/copy_binary.py',
|
||||||
|
'<@(_inputs)',
|
||||||
|
'<@(_outputs)',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}, # copy_chromedriver
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS=="mac"', {
|
['OS=="mac"', {
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "atom/common/chrome_version.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
AtomContentClient::AtomContentClient() {
|
AtomContentClient::AtomContentClient() {
|
||||||
|
@ -15,6 +17,10 @@ AtomContentClient::AtomContentClient() {
|
||||||
AtomContentClient::~AtomContentClient() {
|
AtomContentClient::~AtomContentClient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string AtomContentClient::GetProduct() const {
|
||||||
|
return "Chrome/" CHROME_VERSION_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
void AtomContentClient::AddAdditionalSchemes(
|
void AtomContentClient::AddAdditionalSchemes(
|
||||||
std::vector<std::string>* standard_schemes,
|
std::vector<std::string>* standard_schemes,
|
||||||
std::vector<std::string>* savable_schemes) {
|
std::vector<std::string>* savable_schemes) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ class AtomContentClient : public brightray::ContentClient {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// content::ContentClient:
|
// content::ContentClient:
|
||||||
|
virtual std::string GetProduct() const OVERRIDE;
|
||||||
virtual void AddAdditionalSchemes(
|
virtual void AddAdditionalSchemes(
|
||||||
std::vector<std::string>* standard_schemes,
|
std::vector<std::string>* standard_schemes,
|
||||||
std::vector<std::string>* savable_schemes) OVERRIDE;
|
std::vector<std::string>* savable_schemes) OVERRIDE;
|
||||||
|
|
|
@ -11,11 +11,13 @@ app.on('window-all-closed', function() {
|
||||||
|
|
||||||
// Parse command line options.
|
// Parse command line options.
|
||||||
var argv = process.argv.slice(1);
|
var argv = process.argv.slice(1);
|
||||||
var option = { file: null, version: null };
|
var option = { file: null, version: null, webdriver: null };
|
||||||
for (var i in argv) {
|
for (var i in argv) {
|
||||||
if (argv[i] == '--version' || argv[i] == '-v') {
|
if (argv[i] == '--version' || argv[i] == '-v') {
|
||||||
option.version = true;
|
option.version = true;
|
||||||
break;
|
break;
|
||||||
|
} else if (argv[i] == '--test-type=webdriver') {
|
||||||
|
option.webdriver = true;
|
||||||
} else if (argv[i][0] == '-') {
|
} else if (argv[i][0] == '-') {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -26,7 +28,7 @@ for (var i in argv) {
|
||||||
|
|
||||||
// Start the specified app if there is one specified in command line, otherwise
|
// Start the specified app if there is one specified in command line, otherwise
|
||||||
// start the default app.
|
// start the default app.
|
||||||
if (option.file) {
|
if (option.file && !option.webdriver) {
|
||||||
try {
|
try {
|
||||||
// Override app name and version.
|
// Override app name and version.
|
||||||
var packagePath = path.resolve(option.file);
|
var packagePath = path.resolve(option.file);
|
||||||
|
|
|
@ -67,6 +67,14 @@ const char* kWebRuntimeFeatures[] = {
|
||||||
switches::kSharedWorker,
|
switches::kSharedWorker,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string RemoveWhitespace(const std::string& str) {
|
||||||
|
std::string trimmed;
|
||||||
|
if (base::RemoveChars(str, " ", &trimmed))
|
||||||
|
return trimmed;
|
||||||
|
else
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NativeWindow::NativeWindow(content::WebContents* web_contents,
|
NativeWindow::NativeWindow(content::WebContents* web_contents,
|
||||||
|
@ -106,8 +114,8 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
|
||||||
// Override the user agent to contain application and atom-shell's version.
|
// Override the user agent to contain application and atom-shell's version.
|
||||||
Browser* browser = Browser::Get();
|
Browser* browser = Browser::Get();
|
||||||
std::string product_name = base::StringPrintf(
|
std::string product_name = base::StringPrintf(
|
||||||
"%s/%s Chrome/%s Atom-Shell/" ATOM_VERSION_STRING,
|
"%s/%s Chrome/%s AtomShell/" ATOM_VERSION_STRING,
|
||||||
browser->GetName().c_str(),
|
RemoveWhitespace(browser->GetName()).c_str(),
|
||||||
browser->GetVersion().c_str(),
|
browser->GetVersion().c_str(),
|
||||||
CHROME_VERSION_STRING);
|
CHROME_VERSION_STRING);
|
||||||
web_contents->GetMutableRendererPrefs()->user_agent_override =
|
web_contents->GetMutableRendererPrefs()->user_agent_override =
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
* [Quick start](tutorial/quick-start.md)
|
* [Quick start](tutorial/quick-start.md)
|
||||||
* [Application distribution](tutorial/application-distribution.md)
|
* [Application distribution](tutorial/application-distribution.md)
|
||||||
* [Use native node modules](tutorial/use-native-node-modules.md)
|
* [Using native node modules](tutorial/using-native-node-modules.md)
|
||||||
* [Debugging browser process](tutorial/debugging-browser-process.md)
|
* [Debugging browser process](tutorial/debugging-browser-process.md)
|
||||||
|
* [Using Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md)
|
||||||
* [DevTools extension](tutorial/devtools-extension.md)
|
* [DevTools extension](tutorial/devtools-extension.md)
|
||||||
|
|
||||||
## API references
|
## API references
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Use native Node modules
|
# Usng native Node modules
|
||||||
|
|
||||||
The native Node modules are supported by atom-shell, but since atom-shell is
|
The native Node modules are supported by atom-shell, but since atom-shell is
|
||||||
using a different V8 version from official Node, you need to use `apm` instead
|
using a different V8 version from official Node, you need to use `apm` instead
|
68
docs/tutorial/using-selenium-and-webdriver.md
Normal file
68
docs/tutorial/using-selenium-and-webdriver.md
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
# Using Selenium and WebDriver
|
||||||
|
|
||||||
|
From [chromedriver - WebDriver for Google Chrome][chrome-driver]:
|
||||||
|
|
||||||
|
> WebDriver is an open source tool for automated testing of web apps across many
|
||||||
|
> browsers. It provides capabilities for navigating to web pages, user input,
|
||||||
|
> JavaScript execution, and more. ChromeDriver is a standalone server which
|
||||||
|
> implements WebDriver's wire protocol for Chromium. It is being developed by
|
||||||
|
> members of the Chromium and WebDriver teams.
|
||||||
|
|
||||||
|
In atom-shell's [releases](https://github.com/atom/atom-shell/releases) page you
|
||||||
|
can find archives of `chromedriver`, there is no difference between atom-shell's
|
||||||
|
distribution of `chromedriver` and upstream ones, so in order to use
|
||||||
|
`chromedriver` together with atom-shell, you will need some special setup.
|
||||||
|
|
||||||
|
## Setting up with WebDriverJs
|
||||||
|
|
||||||
|
[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provided
|
||||||
|
a Node package for testing with web driver, we will use it as an example.
|
||||||
|
|
||||||
|
### 1. Start chrome driver
|
||||||
|
|
||||||
|
First you need to download the `chromedriver` binary, and run it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./chromedriver
|
||||||
|
Starting ChromeDriver (v2.10.291558) on port 9515
|
||||||
|
Only local connections are allowed.
|
||||||
|
```
|
||||||
|
|
||||||
|
Remember the port number `9515`, which will be used later
|
||||||
|
|
||||||
|
### 2. Install WebDriverJS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install selenium-webdriver
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Connect to chrome driver
|
||||||
|
|
||||||
|
The usage of `selenium-webdriver` with atom-shell is basically the same with
|
||||||
|
upstream, except that you have to manually specify how to connect chrome driver
|
||||||
|
and where to find atom-shell's binary:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var webdriver = require('selenium-webdriver');
|
||||||
|
|
||||||
|
var driver = new webdriver.Builder().
|
||||||
|
// The "9515" is the port opened by chrome driver.
|
||||||
|
usingServer('http://localhost:9515').
|
||||||
|
withCapabilities({chromeOptions: {
|
||||||
|
// Here is the path to your atom-shell binary.
|
||||||
|
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}}).
|
||||||
|
build();
|
||||||
|
|
||||||
|
driver.get('http://www.google.com');
|
||||||
|
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
|
||||||
|
driver.findElement(webdriver.By.name('btnG')).click();
|
||||||
|
driver.wait(function() {
|
||||||
|
return driver.getTitle().then(function(title) {
|
||||||
|
return title === 'webdriver - Google Search';
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
driver.quit();
|
||||||
|
```
|
||||||
|
|
||||||
|
[chrome-driver]: https://code.google.com/p/chromedriver/
|
|
@ -104,6 +104,7 @@ def main():
|
||||||
download_libchromiumcontent_symbols(args.url)
|
download_libchromiumcontent_symbols(args.url)
|
||||||
create_symbols()
|
create_symbols()
|
||||||
copy_binaries()
|
copy_binaries()
|
||||||
|
copy_chromedriver()
|
||||||
copy_headers()
|
copy_headers()
|
||||||
copy_license()
|
copy_license()
|
||||||
|
|
||||||
|
@ -112,6 +113,7 @@ def main():
|
||||||
|
|
||||||
create_version()
|
create_version()
|
||||||
create_dist_zip()
|
create_dist_zip()
|
||||||
|
create_chromedriver_zip()
|
||||||
create_symbols_zip()
|
create_symbols_zip()
|
||||||
create_header_tarball()
|
create_header_tarball()
|
||||||
|
|
||||||
|
@ -142,6 +144,11 @@ def copy_binaries():
|
||||||
symlinks=True)
|
symlinks=True)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_chromedriver():
|
||||||
|
build = os.path.join(SOURCE_ROOT, 'script', 'build.py')
|
||||||
|
execute([sys.executable, build, '-c', 'Release', '-t', 'copy_chromedriver'])
|
||||||
|
|
||||||
|
|
||||||
def copy_headers():
|
def copy_headers():
|
||||||
os.mkdir(DIST_HEADERS_DIR)
|
os.mkdir(DIST_HEADERS_DIR)
|
||||||
# Copy standard node headers from node. repository.
|
# Copy standard node headers from node. repository.
|
||||||
|
@ -232,6 +239,20 @@ def create_dist_zip():
|
||||||
make_zip(zip_file, files, dirs)
|
make_zip(zip_file, files, dirs)
|
||||||
|
|
||||||
|
|
||||||
|
def create_chromedriver_zip():
|
||||||
|
dist_name = 'chromedriver-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION,
|
||||||
|
TARGET_PLATFORM, DIST_ARCH)
|
||||||
|
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
|
||||||
|
|
||||||
|
with scoped_cwd(DIST_DIR):
|
||||||
|
files = ['LICENSE']
|
||||||
|
if TARGET_PLATFORM == 'win32':
|
||||||
|
files += ['chromedriver.exe']
|
||||||
|
else:
|
||||||
|
files += ['chromedriver']
|
||||||
|
make_zip(zip_file, files, [])
|
||||||
|
|
||||||
|
|
||||||
def create_symbols_zip():
|
def create_symbols_zip():
|
||||||
dist_name = 'atom-shell-{0}-{1}-{2}-symbols.zip'.format(ATOM_SHELL_VERSION,
|
dist_name = 'atom-shell-{0}-{1}-{2}-symbols.zip'.format(ATOM_SHELL_VERSION,
|
||||||
TARGET_PLATFORM,
|
TARGET_PLATFORM,
|
||||||
|
|
|
@ -26,6 +26,9 @@ DIST_NAME = 'atom-shell-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION,
|
||||||
SYMBOLS_NAME = 'atom-shell-{0}-{1}-{2}-symbols.zip'.format(ATOM_SHELL_VERSION,
|
SYMBOLS_NAME = 'atom-shell-{0}-{1}-{2}-symbols.zip'.format(ATOM_SHELL_VERSION,
|
||||||
TARGET_PLATFORM,
|
TARGET_PLATFORM,
|
||||||
DIST_ARCH)
|
DIST_ARCH)
|
||||||
|
CHROMEDRIVER_NAME = 'chromedriver-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION,
|
||||||
|
TARGET_PLATFORM,
|
||||||
|
DIST_ARCH)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -48,6 +51,8 @@ def main():
|
||||||
release_id = create_or_get_release_draft(github, args.version)
|
release_id = create_or_get_release_draft(github, args.version)
|
||||||
upload_atom_shell(github, release_id, os.path.join(DIST_DIR, DIST_NAME))
|
upload_atom_shell(github, release_id, os.path.join(DIST_DIR, DIST_NAME))
|
||||||
upload_atom_shell(github, release_id, os.path.join(DIST_DIR, SYMBOLS_NAME))
|
upload_atom_shell(github, release_id, os.path.join(DIST_DIR, SYMBOLS_NAME))
|
||||||
|
upload_atom_shell(github, release_id,
|
||||||
|
os.path.join(DIST_DIR, CHROMEDRIVER_NAME))
|
||||||
|
|
||||||
# Upload node's headers to S3.
|
# Upload node's headers to S3.
|
||||||
bucket, access_key, secret_key = s3_config()
|
bucket, access_key, secret_key = s3_config()
|
||||||
|
|
12
tools/copy_binary.py
Executable file
12
tools/copy_binary.py
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import stat
|
||||||
|
import sys
|
||||||
|
|
||||||
|
src = sys.argv[1]
|
||||||
|
dist = sys.argv[2]
|
||||||
|
|
||||||
|
shutil.copyfile(src, dist)
|
||||||
|
os.chmod(dist, os.stat(dist).st_mode | stat.S_IEXEC)
|
Loading…
Add table
Add a link
Reference in a new issue