selenium-webdriver 3.6.0 → 4.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +181 -0
- package/README.md +25 -27
- package/chrome.js +113 -127
- package/edge.js +42 -117
- package/example/chrome_android.js +8 -8
- package/example/chrome_mobile_emulation.js +8 -8
- package/example/firefox_channels.js +22 -18
- package/example/google_search_test.js +39 -26
- package/example/logging.js +39 -6
- package/firefox.js +769 -0
- package/http/index.js +41 -4
- package/http/util.js +11 -6
- package/ie.js +56 -97
- package/index.js +178 -114
- package/jasmine.json +11 -0
- package/lib/actions.js +68 -63
- package/lib/by.js +1 -1
- package/lib/capabilities.js +255 -192
- package/lib/command.js +26 -50
- package/lib/error.js +85 -44
- package/lib/http.js +133 -110
- package/lib/input.js +1044 -8
- package/lib/promise.js +222 -3323
- package/lib/proxy.js +134 -39
- package/lib/test/bootstrap_jasmine.js +28 -0
- package/lib/test/data/actions/click.html +24 -0
- package/lib/test/data/actions/drag.html +77 -0
- package/lib/test/data/actions/record_click.html +21 -0
- package/lib/test/data/chrome/download.html +2 -0
- package/lib/test/data/inputs.html +42 -0
- package/lib/test/data/selectPage.html +12 -0
- package/lib/test/data/simpleTest.html +5 -0
- package/lib/test/data/upload_invisible.html +45 -0
- package/lib/test/fileserver.js +23 -19
- package/lib/test/index.js +30 -212
- package/lib/test/resources.js +0 -1
- package/lib/webdriver.js +675 -936
- package/net/index.js +21 -25
- package/net/portprober.js +51 -68
- package/package.json +5 -3
- package/remote/index.js +5 -19
- package/safari.js +41 -128
- package/test/actions_test.js +173 -18
- package/test/{session_test.js → builder_test.js} +44 -37
- package/test/chrome/devtools_test.js +93 -0
- package/test/chrome/options_test.js +48 -154
- package/test/chrome/service_test.js +7 -7
- package/test/cookie_test.js +77 -63
- package/test/element_finding_test.js +206 -201
- package/test/execute_script_test.js +115 -114
- package/test/fingerprint_test.js +16 -15
- package/test/firefox_test.js +251 -0
- package/test/http/http_test.js +0 -1
- package/test/http/util_test.js +2 -2
- package/test/io/zip_test.js +6 -7
- package/test/lib/error_test.js +34 -7
- package/test/lib/http_test.js +8 -128
- package/test/lib/input_test.js +1379 -0
- package/test/lib/promise_test.js +473 -908
- package/test/lib/webdriver_test.js +296 -868
- package/test/logging_test.js +37 -43
- package/test/page_loading_test.js +71 -81
- package/test/proxy_test.js +64 -72
- package/test/rect_test.js +14 -25
- package/test/remote_test.js +10 -29
- package/test/safari_test.js +7 -71
- package/test/stale_element_test.js +20 -23
- package/test/tag_name_test.js +10 -9
- package/test/upload_test.js +27 -35
- package/test/window_test.js +72 -85
- package/testing/index.js +386 -314
- package/.npmignore +0 -2
- package/example/async_await_test.js +0 -69
- package/example/google_search_generator.js +0 -47
- package/example/parallel_flows.js +0 -51
- package/firefox/binary.js +0 -347
- package/firefox/extension.js +0 -224
- package/firefox/index.js +0 -576
- package/firefox/profile.js +0 -311
- package/lib/events.js +0 -210
- package/lib/test/data/firefox/jetpack-sample.xpi +0 -0
- package/lib/test/data/firefox/sample.xpi +0 -0
- package/lib/test/promise.js +0 -79
- package/opera.js +0 -405
- package/phantomjs.js +0 -282
- package/test/firefox/extension_test.js +0 -120
- package/test/firefox/firefox_test.js +0 -244
- package/test/firefox/profile_test.js +0 -140
- package/test/lib/events_test.js +0 -177
- package/test/lib/promise_aplus_test.js +0 -78
- package/test/lib/promise_error_test.js +0 -884
- package/test/lib/promise_flow_test.js +0 -2288
- package/test/lib/promise_generator_test.js +0 -310
- package/test/phantomjs/execute_phantomjs_test.js +0 -59
- package/test/testing/assert_test.js +0 -373
- package/test/testing/index_test.js +0 -224
- package/testing/assert.js +0 -378
package/lib/proxy.js
CHANGED
|
@@ -18,26 +18,126 @@
|
|
|
18
18
|
/**
|
|
19
19
|
* @fileoverview Defines functions for configuring a webdriver proxy:
|
|
20
20
|
*
|
|
21
|
-
* const
|
|
21
|
+
* const proxy = require('selenium-webdriver/proxy');
|
|
22
|
+
* const {Capabilities} = require('selenium-webdriver');
|
|
22
23
|
*
|
|
23
|
-
*
|
|
24
|
+
* let capabilities = new Capabilities();
|
|
24
25
|
* capabilities.setProxy(proxy.manual({http: 'host:1234'});
|
|
25
26
|
*/
|
|
26
27
|
|
|
27
28
|
'use strict';
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Supported {@linkplain Config proxy configuration} types.
|
|
32
|
+
*
|
|
33
|
+
* @enum {string}
|
|
34
|
+
*/
|
|
35
|
+
const Type = {
|
|
36
|
+
AUTODETECT: 'autodetect',
|
|
37
|
+
DIRECT: 'direct',
|
|
38
|
+
MANUAL: 'manual',
|
|
39
|
+
PAC: 'pac',
|
|
40
|
+
SYSTEM: 'system',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Describes how a proxy should be configured for a WebDriver session.
|
|
46
|
+
* @record
|
|
47
|
+
*/
|
|
48
|
+
function Config() {}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The proxy type.
|
|
52
|
+
* @type {Type}
|
|
53
|
+
*/
|
|
54
|
+
Config.prototype.proxyType;
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Describes how to configure a PAC proxy.
|
|
59
|
+
* @record
|
|
60
|
+
* @extends {Config}
|
|
61
|
+
*/
|
|
62
|
+
function PacConfig() {}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* URL for the PAC file to use.
|
|
66
|
+
*
|
|
67
|
+
* @type {string}
|
|
68
|
+
*/
|
|
69
|
+
PacConfig.prototype.proxyAutoconfigUrl;
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Record object that defines a manual proxy configuration. Manual
|
|
74
|
+
* configurations can be easily created using either the
|
|
75
|
+
* {@link ./proxy.manual proxy.manual()} or {@link ./proxy.socks proxy.socks()}
|
|
76
|
+
* factory method.
|
|
77
|
+
*
|
|
78
|
+
* @record
|
|
79
|
+
* @extends {Config}
|
|
80
|
+
*/
|
|
81
|
+
function ManualConfig() {}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The proxy host for FTP requests.
|
|
85
|
+
*
|
|
86
|
+
* @type {(string|undefined)}
|
|
87
|
+
*/
|
|
88
|
+
ManualConfig.prototype.ftpProxy;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The proxy host for HTTP requests.
|
|
92
|
+
*
|
|
93
|
+
* @type {(string|undefined)}
|
|
94
|
+
*/
|
|
95
|
+
ManualConfig.prototype.httpProxy;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* An array of hosts which should bypass all proxies.
|
|
99
|
+
*
|
|
100
|
+
* @type {(Array<string>|undefined)}
|
|
101
|
+
*/
|
|
102
|
+
ManualConfig.prototype.noProxy;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The proxy host for HTTPS requests.
|
|
106
|
+
*
|
|
107
|
+
* @type {(string|undefined)}
|
|
108
|
+
*/
|
|
109
|
+
ManualConfig.prototype.sslProxy;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Defines the host and port for the SOCKS proxy to use.
|
|
113
|
+
*
|
|
114
|
+
* @type {(number|undefined)}
|
|
115
|
+
*/
|
|
116
|
+
ManualConfig.prototype.socksProxy;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Defines the SOCKS proxy version. Must be a number in the range [0, 255].
|
|
120
|
+
*
|
|
121
|
+
* @type {(number|undefined)}
|
|
122
|
+
*/
|
|
123
|
+
ManualConfig.prototype.socksVersion;
|
|
30
124
|
|
|
31
125
|
|
|
32
126
|
// PUBLIC API
|
|
33
127
|
|
|
34
128
|
|
|
129
|
+
/** @const */ exports.Config = Config;
|
|
130
|
+
/** @const */ exports.ManualConfig = ManualConfig;
|
|
131
|
+
/** @const */ exports.PacConfig = PacConfig;
|
|
132
|
+
/** @const */ exports.Type = Type;
|
|
133
|
+
|
|
134
|
+
|
|
35
135
|
/**
|
|
36
136
|
* Configures WebDriver to bypass all browser proxies.
|
|
37
|
-
* @return {!
|
|
137
|
+
* @return {!Config} A new proxy configuration object.
|
|
38
138
|
*/
|
|
39
139
|
exports.direct = function() {
|
|
40
|
-
return {proxyType:
|
|
140
|
+
return {proxyType: Type.DIRECT};
|
|
41
141
|
};
|
|
42
142
|
|
|
43
143
|
|
|
@@ -58,21 +158,18 @@ exports.direct = function() {
|
|
|
58
158
|
* @param {{ftp: (string|undefined),
|
|
59
159
|
* http: (string|undefined),
|
|
60
160
|
* https: (string|undefined),
|
|
61
|
-
* bypass: (
|
|
161
|
+
* bypass: (Array<string>|undefined)}} options Proxy
|
|
62
162
|
* configuration options.
|
|
63
|
-
* @return {!
|
|
64
|
-
*/
|
|
65
|
-
exports.manual = function(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
noProxy: Array.isArray(options.bypass) ?
|
|
74
|
-
options.bypass.join(',') : options.bypass
|
|
75
|
-
});
|
|
163
|
+
* @return {!ManualConfig} A new proxy configuration object.
|
|
164
|
+
*/
|
|
165
|
+
exports.manual = function({ftp, http, https, bypass}) {
|
|
166
|
+
return {
|
|
167
|
+
proxyType: Type.MANUAL,
|
|
168
|
+
ftpProxy: ftp,
|
|
169
|
+
httpProxy: http,
|
|
170
|
+
sslProxy: https,
|
|
171
|
+
noProxy: bypass,
|
|
172
|
+
};
|
|
76
173
|
};
|
|
77
174
|
|
|
78
175
|
|
|
@@ -85,21 +182,22 @@ exports.manual = function(options) {
|
|
|
85
182
|
* const proxy = require('selenium-webdriver/lib/proxy');
|
|
86
183
|
*
|
|
87
184
|
* let capabilities = new Capabilities();
|
|
88
|
-
* capabilities.setProxy(proxy.socks('localhost:1234'
|
|
185
|
+
* capabilities.setProxy(proxy.socks('localhost:1234'));
|
|
89
186
|
*
|
|
187
|
+
* // Or, to include authentication.
|
|
188
|
+
* capabilities.setProxy(proxy.socks('bob:password@localhost:1234'));
|
|
90
189
|
*
|
|
91
|
-
*
|
|
92
|
-
* @param {string}
|
|
93
|
-
* @param {
|
|
94
|
-
* @return {!
|
|
190
|
+
*
|
|
191
|
+
* @param {string} socksProxy The proxy host, in the form `hostname:port`.
|
|
192
|
+
* @param {number=} socksVersion The SOCKS proxy version.
|
|
193
|
+
* @return {!ManualConfig} A new proxy configuration object.
|
|
95
194
|
* @see https://en.wikipedia.org/wiki/SOCKS
|
|
96
195
|
*/
|
|
97
|
-
exports.socks = function(
|
|
98
|
-
return /** @type {!
|
|
99
|
-
proxyType:
|
|
100
|
-
socksProxy
|
|
101
|
-
|
|
102
|
-
socksPassword: password
|
|
196
|
+
exports.socks = function(socksProxy, socksVersion = undefined) {
|
|
197
|
+
return /** @type {!Config} */({
|
|
198
|
+
proxyType: Type.MANUAL,
|
|
199
|
+
socksProxy,
|
|
200
|
+
socksVersion
|
|
103
201
|
});
|
|
104
202
|
};
|
|
105
203
|
|
|
@@ -107,21 +205,18 @@ exports.socks = function(host, username, password) {
|
|
|
107
205
|
/**
|
|
108
206
|
* Configures WebDriver to configure the browser proxy using the PAC file at
|
|
109
207
|
* the given URL.
|
|
110
|
-
* @param {string}
|
|
111
|
-
* @return {!
|
|
208
|
+
* @param {string} proxyAutoconfigUrl URL for the PAC proxy to use.
|
|
209
|
+
* @return {!PacConfig} A new proxy configuration object.
|
|
112
210
|
*/
|
|
113
|
-
exports.pac = function(
|
|
114
|
-
return {
|
|
115
|
-
proxyType: 'pac',
|
|
116
|
-
proxyAutoconfigUrl: url
|
|
117
|
-
};
|
|
211
|
+
exports.pac = function(proxyAutoconfigUrl) {
|
|
212
|
+
return {proxyType: Type.PAC, proxyAutoconfigUrl};
|
|
118
213
|
};
|
|
119
214
|
|
|
120
215
|
|
|
121
216
|
/**
|
|
122
217
|
* Configures WebDriver to use the current system's proxy.
|
|
123
|
-
* @return {!
|
|
218
|
+
* @return {!Config} A new proxy configuration object.
|
|
124
219
|
*/
|
|
125
220
|
exports.system = function() {
|
|
126
|
-
return {proxyType:
|
|
221
|
+
return {proxyType: Type.SYSTEM};
|
|
127
222
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Licensed to the Software Freedom Conservancy (SFC) under one
|
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
|
3
|
+
// distributed with this work for additional information
|
|
4
|
+
// regarding copyright ownership. The SFC licenses this file
|
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
|
6
|
+
// "License"); you may not use this file except in compliance
|
|
7
|
+
// with the License. You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
|
12
|
+
// software distributed under the License is distributed on an
|
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
// KIND, either express or implied. See the License for the
|
|
15
|
+
// specific language governing permissions and limitations
|
|
16
|
+
// under the License.
|
|
17
|
+
|
|
18
|
+
'use strict';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @fileoverview Defines necessary adapaters for jasmine to have an equivalent
|
|
22
|
+
* API to mocha.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
global.after = global.afterAll;
|
|
26
|
+
global.before = global.beforeAll;
|
|
27
|
+
|
|
28
|
+
global.jasmine.DEFAULT_TIMEOUT_INTERVAL = 120 * 1000;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<style>
|
|
3
|
+
body {
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
}
|
|
7
|
+
#box {
|
|
8
|
+
background: red;
|
|
9
|
+
position: absolute;
|
|
10
|
+
top: 0;
|
|
11
|
+
left: 0;
|
|
12
|
+
width: 100px;
|
|
13
|
+
height: 100px;
|
|
14
|
+
}
|
|
15
|
+
#box.green { background: green; }
|
|
16
|
+
#box.blue { background: blue; }
|
|
17
|
+
</style>
|
|
18
|
+
<body>
|
|
19
|
+
<div id="box" onclick="setColor('green');" ondblclick="setColor('blue');"></div>
|
|
20
|
+
<script>
|
|
21
|
+
function setColor(c) {
|
|
22
|
+
document.getElementById('box').className = c;
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<style>
|
|
3
|
+
body {
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
}
|
|
7
|
+
div {
|
|
8
|
+
position: absolute;
|
|
9
|
+
width: 50px;
|
|
10
|
+
height: 50px;
|
|
11
|
+
left: 0;
|
|
12
|
+
top: 0;
|
|
13
|
+
}
|
|
14
|
+
#TR { left: 206px; }
|
|
15
|
+
#BL { top: 206px; }
|
|
16
|
+
#BR { left: 206px; top: 206px; }
|
|
17
|
+
#container {
|
|
18
|
+
width: 256px;
|
|
19
|
+
height: 256px;
|
|
20
|
+
left: 0;
|
|
21
|
+
top: 0;
|
|
22
|
+
border: 1px solid black;
|
|
23
|
+
}
|
|
24
|
+
#slide {
|
|
25
|
+
background: silver;
|
|
26
|
+
z-index: 1;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
<body>
|
|
30
|
+
<div id="container">
|
|
31
|
+
<div id="slide"></div>
|
|
32
|
+
<div id="TR"></div>
|
|
33
|
+
<div id="BR"></div>
|
|
34
|
+
<div id="BL"></div>
|
|
35
|
+
</div>
|
|
36
|
+
<script>
|
|
37
|
+
let offset;
|
|
38
|
+
let mouseDown = false;
|
|
39
|
+
let slide = document.getElementById('slide');
|
|
40
|
+
slide.addEventListener('mousedown', function(e) {
|
|
41
|
+
mouseDown = true;
|
|
42
|
+
|
|
43
|
+
let bbox = slide.getBoundingClientRect();
|
|
44
|
+
offset = {
|
|
45
|
+
x: e.clientX - bbox.left,
|
|
46
|
+
y: e.clientY - bbox.top
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
let container = document.getElementById('container');
|
|
51
|
+
|
|
52
|
+
let slideBox = slide.getBoundingClientRect();
|
|
53
|
+
let containerBox = container.getBoundingClientRect();
|
|
54
|
+
let maxLeft = containerBox.width - slideBox.width - 2;
|
|
55
|
+
let maxTop = containerBox.height - slideBox.height - 2;
|
|
56
|
+
|
|
57
|
+
container.addEventListener('mousemove', function(e) {
|
|
58
|
+
if (!mouseDown) return;
|
|
59
|
+
|
|
60
|
+
let bbox = slide.getBoundingClientRect();
|
|
61
|
+
let newLeft = e.clientX - offset.x;
|
|
62
|
+
newLeft = Math.max(newLeft, 0);
|
|
63
|
+
newLeft = Math.min(newLeft, maxLeft);
|
|
64
|
+
|
|
65
|
+
let newTop = e.clientY - offset.y;
|
|
66
|
+
newTop = Math.max(newTop, 0);
|
|
67
|
+
newTop = Math.min(newTop, maxTop);
|
|
68
|
+
|
|
69
|
+
slide.style.top = `${newTop}px`;
|
|
70
|
+
slide.style.left = `${newLeft}px`;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
document.body.addEventListener('mouseup', function() {
|
|
74
|
+
mouseDown = false;
|
|
75
|
+
});
|
|
76
|
+
</script>
|
|
77
|
+
</body>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<style>
|
|
3
|
+
body {
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
}
|
|
7
|
+
div {
|
|
8
|
+
position: absolute;
|
|
9
|
+
top: 0;
|
|
10
|
+
left: 0;
|
|
11
|
+
width: 500px;
|
|
12
|
+
height: 500px;
|
|
13
|
+
background: green;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
<div></div>
|
|
17
|
+
<script>
|
|
18
|
+
var clicks = [];
|
|
19
|
+
document.querySelector('div')
|
|
20
|
+
.addEventListener('click', e => clicks.push([e.clientX, e.clientY]));
|
|
21
|
+
</script>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>inputs</title>
|
|
4
|
+
</head>
|
|
5
|
+
<body>
|
|
6
|
+
<h1>Testing Inputs</h1>
|
|
7
|
+
|
|
8
|
+
<form action="#">
|
|
9
|
+
<input name="no_type" value="input with no type" /><br/>
|
|
10
|
+
<br/>
|
|
11
|
+
<input name="number_input" type="number" value="42" /><br/>
|
|
12
|
+
<input name="range_input" type="range" value="42" /><br/>
|
|
13
|
+
<br/>
|
|
14
|
+
<input name="email_input" type="email" value="admin@localhost" /><br/>
|
|
15
|
+
<input name="password_input" type="password" value="qwerty" /><br/>
|
|
16
|
+
<input name="search_input" type="search" value="search" /><br/>
|
|
17
|
+
<input name="tel_input" type="tel" value="911" /><br/>
|
|
18
|
+
<input name="text_input" type="text" value="text input" /><br/>
|
|
19
|
+
<input name="url_input" type="url" value="http://seleniumhq.org/" /><br/>
|
|
20
|
+
<br/>
|
|
21
|
+
<input name="checkbox_input" type="checkbox" value="Checkbox" checked /><br/>
|
|
22
|
+
<input name="radio_input" type="radio" value="radio1" checked /><br/>
|
|
23
|
+
<input name="radio_input" type="radio" value="radio2" /><br/>
|
|
24
|
+
<br/>
|
|
25
|
+
<input name="color_input" type="color" value="#00ffff" /><br/>
|
|
26
|
+
<br/>
|
|
27
|
+
<input name="date_input" type="date" value="2017-11-22" /><br/>
|
|
28
|
+
<input name="datetime_input" type="datetime" value="2017-11-22T11:22" /><br/>
|
|
29
|
+
<input name="datetime_local_input" type="datetime-local" value="2017-11-22T11:22" /><br/>
|
|
30
|
+
<input name="time_input" type="time" value="11:22" /><br/>
|
|
31
|
+
<input name="month_input" type="month" value="2017-11" /><br/>
|
|
32
|
+
<input name="week_input" type="week" value="2017-W47" /><br/>
|
|
33
|
+
<br/>
|
|
34
|
+
<input name="button_input" type="button" value="button" />
|
|
35
|
+
<input name="image_input" type="image" value="image" src="icon.gif" />
|
|
36
|
+
<input name="reset_input" type="reset" value="reset" />
|
|
37
|
+
<input name="submit_input" type="submit" value="submit" />
|
|
38
|
+
|
|
39
|
+
<input name="hidden_input" type="hidden" value="hidden" />
|
|
40
|
+
</form>
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
@@ -54,5 +54,17 @@
|
|
|
54
54
|
<option value="cheddar">Avonlea Clothbound Cheddar</option>
|
|
55
55
|
</select>
|
|
56
56
|
|
|
57
|
+
<select id="visibility">
|
|
58
|
+
<option value="regular" class="regular">Regular</option>
|
|
59
|
+
<option value="disabled" disabled="disabled" class="disabled">Disabled</option>
|
|
60
|
+
<option value="hidden" style="visibility: hidden;" class="hidden">Hidden</option>
|
|
61
|
+
<option value="invisible" style="display: none;" class="invisible">Invisible</option>
|
|
62
|
+
</select>
|
|
63
|
+
|
|
64
|
+
<select id="transparent" style="opacity: 0;">
|
|
65
|
+
<option value="one">one</option>
|
|
66
|
+
<option value="two">two</option>
|
|
67
|
+
</select>
|
|
68
|
+
|
|
57
69
|
</body>
|
|
58
70
|
</html>
|
|
@@ -94,5 +94,10 @@ document.write(" and with document.write again");
|
|
|
94
94
|
|
|
95
95
|
<span id="trimmedSpace"> test </span>
|
|
96
96
|
|
|
97
|
+
<br/>
|
|
98
|
+
<a id="capitalized" style="text-transform: capitalize">Hello, world! bla-bla-BLA</a><br/>
|
|
99
|
+
<a id="lowercased" style="text-transform: lowercase">Hello, world! bla-bla-BLA</a><br/>
|
|
100
|
+
<a id="uppercased" style="text-transform: uppercase">Hello, world! bla-bla-BLA</a><br/>
|
|
101
|
+
|
|
97
102
|
</body>
|
|
98
103
|
</html>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Upload Form</title>
|
|
5
|
+
<script>
|
|
6
|
+
var intervalId;
|
|
7
|
+
function onTick() {
|
|
8
|
+
var label = document.getElementById('upload_label');
|
|
9
|
+
label.innerHTML += '.';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function onUploadSubmit() {
|
|
13
|
+
document.getElementById('upload_target').contentWindow.document.body.
|
|
14
|
+
innerHTML = '';
|
|
15
|
+
var label = document.getElementById('upload_label');
|
|
16
|
+
label.innerHTML = 'Uploading "' + document.forms[0].upload.value + '"';
|
|
17
|
+
label.style.display = '';
|
|
18
|
+
intervalId = window.setInterval(onTick, 500);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function onUploadDone() {
|
|
23
|
+
var label = document.getElementById('upload_label');
|
|
24
|
+
label.style.display = 'none';
|
|
25
|
+
window.clearInterval(intervalId);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
<form action="/common/upload" method="post" name="upload_form"
|
|
32
|
+
target="upload_target" enctype="multipart/form-data"
|
|
33
|
+
onsubmit="onUploadSubmit();">
|
|
34
|
+
<div style='height: 0; width: 0; overflow: hidden;'>
|
|
35
|
+
<div><input id="upload" name="upload" type="file"/></div>
|
|
36
|
+
</div>
|
|
37
|
+
<label id="visible_label" for="upload">Upload</label>
|
|
38
|
+
<div><input id="go" type="submit" value="Go!"/></div>
|
|
39
|
+
<div id="upload_label" style="display:none"></div>
|
|
40
|
+
<iframe src="" id="upload_target" name="upload_target"
|
|
41
|
+
style="width:300px;height:200px">
|
|
42
|
+
</iframe>
|
|
43
|
+
</form>
|
|
44
|
+
</body>
|
|
45
|
+
</html>
|
package/lib/test/fileserver.js
CHANGED
|
@@ -17,26 +17,28 @@
|
|
|
17
17
|
|
|
18
18
|
'use strict';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const http = require('http');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const url = require('url');
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const express = require('express');
|
|
26
|
+
const multer = require('multer');
|
|
27
|
+
const serveIndex = require('serve-index');
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const isDevMode = require('../devmode');
|
|
30
|
+
const resources = require('./resources');
|
|
31
|
+
const {Server} = require('./httpserver');
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const WEB_ROOT = '/common';
|
|
34
|
+
const DATA_ROOT = '/data';
|
|
35
|
+
const JS_ROOT = '/javascript';
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
const baseDirectory = resources.locate(isDevMode ? 'common/src/web' : '.');
|
|
38
|
+
const dataDirectory = path.join(__dirname, 'data');
|
|
39
|
+
const jsDirectory = resources.locate(isDevMode ? 'javascript' : '..');
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
const Pages = (function() {
|
|
40
42
|
var pages = {};
|
|
41
43
|
function addPage(page, path) {
|
|
42
44
|
pages.__defineGetter__(page, function() {
|
|
@@ -105,7 +107,7 @@ var Pages = (function() {
|
|
|
105
107
|
})();
|
|
106
108
|
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
const Path = {
|
|
109
111
|
BASIC_AUTH: WEB_ROOT + '/basicAuth',
|
|
110
112
|
ECHO: WEB_ROOT + '/echo',
|
|
111
113
|
GENERATED: WEB_ROOT + '/generated',
|
|
@@ -126,6 +128,7 @@ app.get('/', sendIndex)
|
|
|
126
128
|
.use(JS_ROOT, serveIndex(jsDirectory), express.static(jsDirectory))
|
|
127
129
|
.post(Path.UPLOAD, handleUpload)
|
|
128
130
|
.use(WEB_ROOT, serveIndex(baseDirectory), express.static(baseDirectory))
|
|
131
|
+
.use(DATA_ROOT, serveIndex(dataDirectory), express.static(dataDirectory))
|
|
129
132
|
.get(Path.ECHO, sendEcho)
|
|
130
133
|
.get(Path.PAGE, sendInifinitePage)
|
|
131
134
|
.get(Path.PAGE + '/*', sendInifinitePage)
|
|
@@ -250,7 +253,8 @@ function sendIndex(request, response) {
|
|
|
250
253
|
}
|
|
251
254
|
|
|
252
255
|
var data = ['<!DOCTYPE html><h1>/</h1><hr/><ul>',
|
|
253
|
-
createListEntry('common')
|
|
256
|
+
createListEntry('common'),
|
|
257
|
+
createListEntry('data')];
|
|
254
258
|
if (isDevMode) {
|
|
255
259
|
data.push(createListEntry('javascript'));
|
|
256
260
|
}
|
|
@@ -305,9 +309,9 @@ exports.url = server.url.bind(server);
|
|
|
305
309
|
exports.whereIs = function(filePath) {
|
|
306
310
|
filePath = filePath.replace(/\\/g, '/');
|
|
307
311
|
if (!filePath.startsWith('/')) {
|
|
308
|
-
filePath =
|
|
312
|
+
filePath = `${WEB_ROOT}/${filePath}`;
|
|
309
313
|
}
|
|
310
|
-
return server.url(
|
|
314
|
+
return server.url(filePath);
|
|
311
315
|
};
|
|
312
316
|
|
|
313
317
|
|