angular_webdriver 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +32 -0
  6. data/Gemfile +2 -0
  7. data/Thorfile +33 -1
  8. data/angular_webdriver.gemspec +10 -3
  9. data/docs/overview.md +101 -0
  10. data/docs/sync.md +53 -0
  11. data/lib/angular_webdriver/protractor/by.rb +331 -0
  12. data/lib/angular_webdriver/protractor/by_repeater_inner.rb +106 -0
  13. data/lib/angular_webdriver/protractor/client_side_scripts.rb +1035 -0
  14. data/lib/angular_webdriver/protractor/protractor.rb +396 -77
  15. data/lib/angular_webdriver/protractor/protractor_element.rb +33 -0
  16. data/lib/angular_webdriver/protractor/rspec_helpers.rb +19 -0
  17. data/lib/angular_webdriver/protractor/watir_patch.rb +209 -0
  18. data/lib/angular_webdriver/protractor/webdriver_patch.rb +246 -0
  19. data/lib/angular_webdriver/version.rb +2 -2
  20. data/lib/angular_webdriver.rb +14 -1
  21. data/{LICENSE → license/angular_webdriver/LICENSE.txt} +0 -0
  22. data/{lib/angular_webdriver → license}/protractor/LICENSE.txt +0 -0
  23. data/{lib/angular_webdriver/protractor/get_url_trace.rb → notes/bootstrap_notes.md} +13 -0
  24. data/notes/element_by_id/element_by_id_sync_off.txt +12 -0
  25. data/notes/element_by_id/element_by_id_sync_on.txt +74 -0
  26. data/notes/element_chaining_debug.txt +94 -0
  27. data/notes/evaluate/js_evaluate_sync_on.txt +60 -0
  28. data/notes/evaluate/ruby_evaluate_sync_on.txt +35 -0
  29. data/notes/get_title/browser_get_title_sync_off.txt +11 -0
  30. data/notes/get_title/browser_get_title_sync_on.txt +54 -0
  31. data/notes/phantomjs.md +23 -0
  32. data/notes/protractor_cli_bugs.txt +39 -0
  33. data/notes/protractor_get/protractor_get.rb +102 -0
  34. data/notes/protractor_get/protractor_get_website_sync_off.txt +11 -0
  35. data/notes/protractor_get/protractor_get_website_sync_on.txt +86 -0
  36. data/notes/repeater/findAllRepeaterRows_annotated.txt +150 -0
  37. data/notes/repeater/findAllRepeaterRows_raw.txt +145 -0
  38. data/notes/repeater/findRepeaterColumn_annotated.txt +317 -0
  39. data/notes/repeater/findRepeaterColumn_raw.txt +310 -0
  40. data/notes/repeater/findRepeaterElement_annotated.txt +152 -0
  41. data/notes/repeater/findRepeaterElement_raw.txt +146 -0
  42. data/notes/repeater/findRepeaterRows_annotated.txt +156 -0
  43. data/notes/repeater/findRepeaterRows_raw.txt +152 -0
  44. data/notes/sync_after.md +46 -0
  45. data/notes/sync_notes.md +137 -0
  46. data/notes/synchronize_spec/status_gettext.txt +121 -0
  47. data/notes/synchronize_spec/status_gettext_x3.txt +451 -0
  48. data/notes/synchronize_spec/synchronize_spec.js.txt +74 -0
  49. data/notes/synchronize_spec/watir_gettext.txt +73 -0
  50. data/readme.md +52 -12
  51. data/release_notes.md +127 -0
  52. data/selenium_server/lib/logs.rb +50 -0
  53. data/selenium_server/lib/selenium_server.rb +21 -0
  54. data/selenium_server/readme.md +3 -0
  55. data/selenium_server/spec/logs_spec.rb +18 -0
  56. data/selenium_server/spec/nodejs_sync_spec_waithttp_annotated.txt +54 -0
  57. data/selenium_server/spec/nodejs_sync_spec_waithttp_raw.txt +367 -0
  58. data/selenium_server/spec/nodejs_sync_spec_waithttp_raw_processed.txt +43 -0
  59. data/selenium_server/spec/ruby_sync_spec_waithttp_annotated.txt +59 -0
  60. data/selenium_server/spec/ruby_sync_spec_waithttp_raw.txt +267 -0
  61. data/selenium_server/spec/ruby_sync_spec_waithttp_raw_processed.txt +39 -0
  62. data/selenium_server/spec/spec_helper.rb +6 -0
  63. data/selenium_server/spec/status_gettext_x3.txt +429 -0
  64. data/selenium_server/spec/status_gettext_x3_annotated.txt +86 -0
  65. metadata +91 -18
  66. data/lib/angular_webdriver/protractor/clientSideScripts.json +0 -19
  67. data/lib/angular_webdriver/protractor/clientsidescripts.js +0 -671
  68. data/lib/angular_webdriver/protractor/scripts.rb +0 -7
  69. data/lib/angular_webdriver/protractor/scripts_to_json.js +0 -11
  70. data/spec/protractor_spec.rb +0 -40
  71. data/spec/spec_helper.rb +0 -5
@@ -0,0 +1,156 @@
1
+ browser.get('http://localhost:8081/#/repeater')
2
+ element(by.repeater('baz in days').row(0)).getText();
3
+
4
+
5
+ 16:14:10.375 INFO - Executing: [execute script: , []])
6
+ 16:14:10.375 INFO - Executing: [execute async script: try { return (function (rootSelector, callback) {
7
+ var el = document.querySelector(rootSelector);
8
+
9
+ try {
10
+ if (!window.angular) {
11
+ throw new Error('angular could not be found on the window');
12
+ }
13
+ if (angular.getTestability) {
14
+ angular.getTestability(el).whenStable(callback);
15
+ } else {
16
+ if (!angular.element(el).injector()) {
17
+ throw new Error('root element (' + rootSelector + ') has no injector.' +
18
+ ' this may mean it is not inside ng-app.');
19
+ }
20
+ angular.element(el).injector().get('$browser').
21
+ notifyWhenNoOutstandingRequests(callback);
22
+ }
23
+ } catch (err) {
24
+ callback(err.message);
25
+ }
26
+ }).apply(this, arguments); }
27
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [body]])
28
+ 16:14:10.390 INFO - Done: [execute script: , []]
29
+ 16:14:10.450 INFO - Done: [execute async script: try { return (function (rootSelector, callback) {
30
+ var el = document.querySelector(rootSelector);
31
+
32
+ try {
33
+ if (!window.angular) {
34
+ throw new Error('angular could not be found on the window');
35
+ }
36
+ if (angular.getTestability) {
37
+ angular.getTestability(el).whenStable(callback);
38
+ } else {
39
+ if (!angular.element(el).injector()) {
40
+ throw new Error('root element (' + rootSelector + ') has no injector.' +
41
+ ' this may mean it is not inside ng-app.');
42
+ }
43
+ angular.element(el).injector().get('$browser').
44
+ notifyWhenNoOutstandingRequests(callback);
45
+ }
46
+ } catch (err) {
47
+ callback(err.message);
48
+ }
49
+ }).apply(this, arguments); }
50
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [body]]
51
+
52
+ // -- function (repeater, exact, index, using)
53
+ // -- [baz in days, false, 0, null, body]
54
+ // -- findRepeaterRows
55
+ 16:14:10.466 INFO - Executing: [execute script: try { return (function (repeater, exact, index, using) {
56
+ function repeaterMatch(ngRepeat, repeater, exact) {
57
+ if (exact) {
58
+ return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].
59
+ trim() == repeater;
60
+ } else {
61
+ return ngRepeat.indexOf(repeater) != -1;
62
+ }
63
+ }
64
+
65
+ using = using || document;
66
+
67
+ var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
68
+ var rows = [];
69
+ for (var p = 0; p < prefixes.length; ++p) {
70
+ var attr = prefixes[p] + 'repeat';
71
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
72
+ attr = attr.replace(/\\/g, '');
73
+ for (var i = 0; i < repeatElems.length; ++i) {
74
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
75
+ rows.push(repeatElems[i]);
76
+ }
77
+ }
78
+ }
79
+ /* multiRows is an array of arrays, where each inner array contains
80
+ one row of elements. */
81
+ var multiRows = [];
82
+ for (var p = 0; p < prefixes.length; ++p) {
83
+ var attr = prefixes[p] + 'repeat-start';
84
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
85
+ attr = attr.replace(/\\/g, '');
86
+ for (var i = 0; i < repeatElems.length; ++i) {
87
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
88
+ var elem = repeatElems[i];
89
+ var row = [];
90
+ while (elem.nodeType != 8 ||
91
+ !repeaterMatch(elem.nodeValue, repeater, exact)) {
92
+ if (elem.nodeType == 1) {
93
+ row.push(elem);
94
+ }
95
+ elem = elem.nextSibling;
96
+ }
97
+ multiRows.push(row);
98
+ }
99
+ }
100
+ }
101
+ var row = rows[index] || [], multiRow = multiRows[index] || [];
102
+ return [].concat(row, multiRow);
103
+ }).apply(this, arguments); }
104
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [baz in days, false, 0, null, body]])
105
+ 16:14:10.553 INFO - Done: [execute script: try { return (function (repeater, exact, index, using) {
106
+ function repeaterMatch(ngRepeat, repeater, exact) {
107
+ if (exact) {
108
+ return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].
109
+ trim() == repeater;
110
+ } else {
111
+ return ngRepeat.indexOf(repeater) != -1;
112
+ }
113
+ }
114
+
115
+ using = using || document;
116
+
117
+ var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
118
+ var rows = [];
119
+ for (var p = 0; p < prefixes.length; ++p) {
120
+ var attr = prefixes[p] + 'repeat';
121
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
122
+ attr = attr.replace(/\\/g, '');
123
+ for (var i = 0; i < repeatElems.length; ++i) {
124
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
125
+ rows.push(repeatElems[i]);
126
+ }
127
+ }
128
+ }
129
+ /* multiRows is an array of arrays, where each inner array contains
130
+ one row of elements. */
131
+ var multiRows = [];
132
+ for (var p = 0; p < prefixes.length; ++p) {
133
+ var attr = prefixes[p] + 'repeat-start';
134
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
135
+ attr = attr.replace(/\\/g, '');
136
+ for (var i = 0; i < repeatElems.length; ++i) {
137
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
138
+ var elem = repeatElems[i];
139
+ var row = [];
140
+ while (elem.nodeType != 8 ||
141
+ !repeaterMatch(elem.nodeValue, repeater, exact)) {
142
+ if (elem.nodeType == 1) {
143
+ row.push(elem);
144
+ }
145
+ elem = elem.nextSibling;
146
+ }
147
+ multiRows.push(row);
148
+ }
149
+ }
150
+ }
151
+ var row = rows[index] || [], multiRow = multiRows[index] || [];
152
+ return [].concat(row, multiRow);
153
+ }).apply(this, arguments); }
154
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [baz in days, false, 0, null, body]]
155
+ 16:14:10.570 INFO - Executing: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@fa534d6b -> unknown locator]])
156
+ 16:14:10.616 INFO - Done: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@fa534d6b -> unknown locator]]
@@ -0,0 +1,152 @@
1
+ browser.get('http://localhost:8081/#/repeater')
2
+ element(by.repeater('baz in days').row(0)).getText();
3
+
4
+
5
+ 16:14:10.375 INFO - Executing: [execute script: , []])
6
+ 16:14:10.375 INFO - Executing: [execute async script: try { return (function (rootSelector, callback) {
7
+ var el = document.querySelector(rootSelector);
8
+
9
+ try {
10
+ if (!window.angular) {
11
+ throw new Error('angular could not be found on the window');
12
+ }
13
+ if (angular.getTestability) {
14
+ angular.getTestability(el).whenStable(callback);
15
+ } else {
16
+ if (!angular.element(el).injector()) {
17
+ throw new Error('root element (' + rootSelector + ') has no injector.' +
18
+ ' this may mean it is not inside ng-app.');
19
+ }
20
+ angular.element(el).injector().get('$browser').
21
+ notifyWhenNoOutstandingRequests(callback);
22
+ }
23
+ } catch (err) {
24
+ callback(err.message);
25
+ }
26
+ }).apply(this, arguments); }
27
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [body]])
28
+ 16:14:10.390 INFO - Done: [execute script: , []]
29
+ 16:14:10.450 INFO - Done: [execute async script: try { return (function (rootSelector, callback) {
30
+ var el = document.querySelector(rootSelector);
31
+
32
+ try {
33
+ if (!window.angular) {
34
+ throw new Error('angular could not be found on the window');
35
+ }
36
+ if (angular.getTestability) {
37
+ angular.getTestability(el).whenStable(callback);
38
+ } else {
39
+ if (!angular.element(el).injector()) {
40
+ throw new Error('root element (' + rootSelector + ') has no injector.' +
41
+ ' this may mean it is not inside ng-app.');
42
+ }
43
+ angular.element(el).injector().get('$browser').
44
+ notifyWhenNoOutstandingRequests(callback);
45
+ }
46
+ } catch (err) {
47
+ callback(err.message);
48
+ }
49
+ }).apply(this, arguments); }
50
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [body]]
51
+ 16:14:10.466 INFO - Executing: [execute script: try { return (function (repeater, exact, index, using) {
52
+ function repeaterMatch(ngRepeat, repeater, exact) {
53
+ if (exact) {
54
+ return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].
55
+ trim() == repeater;
56
+ } else {
57
+ return ngRepeat.indexOf(repeater) != -1;
58
+ }
59
+ }
60
+
61
+ using = using || document;
62
+
63
+ var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
64
+ var rows = [];
65
+ for (var p = 0; p < prefixes.length; ++p) {
66
+ var attr = prefixes[p] + 'repeat';
67
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
68
+ attr = attr.replace(/\\/g, '');
69
+ for (var i = 0; i < repeatElems.length; ++i) {
70
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
71
+ rows.push(repeatElems[i]);
72
+ }
73
+ }
74
+ }
75
+ /* multiRows is an array of arrays, where each inner array contains
76
+ one row of elements. */
77
+ var multiRows = [];
78
+ for (var p = 0; p < prefixes.length; ++p) {
79
+ var attr = prefixes[p] + 'repeat-start';
80
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
81
+ attr = attr.replace(/\\/g, '');
82
+ for (var i = 0; i < repeatElems.length; ++i) {
83
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
84
+ var elem = repeatElems[i];
85
+ var row = [];
86
+ while (elem.nodeType != 8 ||
87
+ !repeaterMatch(elem.nodeValue, repeater, exact)) {
88
+ if (elem.nodeType == 1) {
89
+ row.push(elem);
90
+ }
91
+ elem = elem.nextSibling;
92
+ }
93
+ multiRows.push(row);
94
+ }
95
+ }
96
+ }
97
+ var row = rows[index] || [], multiRow = multiRows[index] || [];
98
+ return [].concat(row, multiRow);
99
+ }).apply(this, arguments); }
100
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [baz in days, false, 0, null, body]])
101
+ 16:14:10.553 INFO - Done: [execute script: try { return (function (repeater, exact, index, using) {
102
+ function repeaterMatch(ngRepeat, repeater, exact) {
103
+ if (exact) {
104
+ return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].
105
+ trim() == repeater;
106
+ } else {
107
+ return ngRepeat.indexOf(repeater) != -1;
108
+ }
109
+ }
110
+
111
+ using = using || document;
112
+
113
+ var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
114
+ var rows = [];
115
+ for (var p = 0; p < prefixes.length; ++p) {
116
+ var attr = prefixes[p] + 'repeat';
117
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
118
+ attr = attr.replace(/\\/g, '');
119
+ for (var i = 0; i < repeatElems.length; ++i) {
120
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
121
+ rows.push(repeatElems[i]);
122
+ }
123
+ }
124
+ }
125
+ /* multiRows is an array of arrays, where each inner array contains
126
+ one row of elements. */
127
+ var multiRows = [];
128
+ for (var p = 0; p < prefixes.length; ++p) {
129
+ var attr = prefixes[p] + 'repeat-start';
130
+ var repeatElems = using.querySelectorAll('[' + attr + ']');
131
+ attr = attr.replace(/\\/g, '');
132
+ for (var i = 0; i < repeatElems.length; ++i) {
133
+ if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
134
+ var elem = repeatElems[i];
135
+ var row = [];
136
+ while (elem.nodeType != 8 ||
137
+ !repeaterMatch(elem.nodeValue, repeater, exact)) {
138
+ if (elem.nodeType == 1) {
139
+ row.push(elem);
140
+ }
141
+ elem = elem.nextSibling;
142
+ }
143
+ multiRows.push(row);
144
+ }
145
+ }
146
+ }
147
+ var row = rows[index] || [], multiRow = multiRows[index] || [];
148
+ return [].concat(row, multiRow);
149
+ }).apply(this, arguments); }
150
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [baz in days, false, 0, null, body]]
151
+ 16:14:10.570 INFO - Executing: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@fa534d6b -> unknown locator]])
152
+ 16:14:10.616 INFO - Done: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@fa534d6b -> unknown locator]]
@@ -0,0 +1,46 @@
1
+ Due to protractors design (lazy loading of elements and always refinding elements)
2
+ there's no need for syncing after an element action. This is because every
3
+ element action causes the element to be refound which triggers wait for angular.
4
+
5
+ These are some notes about sync_after which ended up not being used.
6
+ Instead the protractor semantics are matched by adopting watir-webdriver.
7
+
8
+ ```ruby
9
+ # do not use. will be removed
10
+ def sync_after webdriver_command
11
+ # https://github.com/angular/protractor/blob/8743d5cdf4c6b1337f5a4bd376336911cf62b856/lib/element.js#L5
12
+ # var WEB_ELEMENT_FUNCTIONS
13
+ #
14
+ # 'click', # :clickElement,
15
+ # 'sendKeys', # :sendKeysToElement, :sendKeysToActiveElement, :sendModifierKeyToActiveElement
16
+ # 'getTagName', # :getElementTagName
17
+ # 'getCssValue', # getElementValueOfCssProperty
18
+ # 'getAttribute', # :getElementAttribute
19
+ # 'getText', # :getElementText
20
+ # 'getSize', # :getElementSize,
21
+ # 'getLocation', # :getElementLocation, :getElementLocationOnceScrolledIntoView
22
+ # 'isEnabled', # :isElementEnabled
23
+ # 'isSelected', # :isElementSelected
24
+ # 'submit', # :submitElement
25
+ # 'clear', # :clearElement
26
+ # 'isDisplayed', # :isElementDisplayed
27
+ # 'getOuterHtml', -- JS binding exclusive. not available in Ruby bindings.
28
+ # 'getInnerHtml', -- JS binding exclusive. not available in Ruby bindings.
29
+ # 'getId', # :describeElement
30
+ # 'getRawId']; # same as element.ref however in Ruby this is purely client side.
31
+
32
+
33
+ # todo: audit all web element functions (protractor element.js)
34
+ # so that the sync test can pass.
35
+ # commdands.rb
36
+
37
+
38
+ # todo: evaluate these
39
+ # :getElementValue
40
+ # :dragElement
41
+ # :getActiveElement
42
+ # elementEquals
43
+
44
+
45
+ end
46
+ ```
@@ -0,0 +1,137 @@
1
+ sync on find element(s) calls
2
+ browser.get('https://angularjs.org/')
3
+ element(by.id('the-basics')).getText()
4
+
5
+
6
+ protractor.js
7
+
8
+ var methodsToSync = ['getCurrentUrl', 'getPageSource', 'getTitle']; -- all of these wait for angular
9
+
10
+ Protractor.prototype.findElement -- waits for angular
11
+ Protractor.prototype.findElements -- waits for angular
12
+
13
+ Protractor.prototype.isElementPresent -- does **not** trigger wait for angular
14
+
15
+ Protractor.prototype.get -- custom protractor method, waits for angular
16
+ Protractor.prototype.refresh -- custom protractor method, waits for angular
17
+ Protractor.prototype.navigate -- does not trigger wait for angular
18
+
19
+ Protractor.prototype.setLocation -- custom protractor method -- client side script that already checks for angular.
20
+ Protractor.prototype.getLocationAbsUrl -- custom protractor method -- client side script that already checks for angular.
21
+ Protractor.prototype.debugger -- custom protractor method -- client side script. doesn't wait.
22
+
23
+
24
+ todo: port custom protractor methods
25
+ todo: auto sync / use protractor replacements when ignore sync is false
26
+
27
+
28
+ redefine core selenium methods to auto sync before execution
29
+ to use commands (for example get) on non-angular pages, people can disable synchronization.
30
+
31
+ # ---
32
+
33
+ Selenium::WebDriver::Remote::COMMANDS.keys
34
+ => [:newSession,
35
+ :getCapabilities,
36
+ :status,
37
+ :getCurrentUrl, -- must sync
38
+ :get, -- must sync
39
+ :goForward, -- does not sync
40
+ :goBack, -- does not sync
41
+ :refresh, -- must sync
42
+ :quit,
43
+ :close,
44
+ :getPageSource, -- must sync
45
+ :getTitle, -- must sync
46
+ :findElement, -- must sync
47
+ :findElements, -- must sync
48
+ :getActiveElement, -- does not sync
49
+ :getCurrentWindowHandle, -- does not sync
50
+ :getWindowHandles,
51
+ :setWindowSize,
52
+ :setWindowPosition,
53
+ :getWindowSize, -- does not sync
54
+ :getWindowPosition, -- does not sync
55
+ :maximizeWindow,
56
+ :executeScript, -- does not sync
57
+ :executeAsyncScript, -- does not sync
58
+ :screenshot,
59
+ :dismissAlert,
60
+ :acceptAlert,
61
+ :getAlertText, -- does not sync
62
+ :setAlertValue,
63
+ :switchToFrame,
64
+ :switchToParentFrame,
65
+ :switchToWindow,
66
+ :getCookies,
67
+ :addCookie,
68
+ :deleteAllCookies,
69
+ :deleteCookie,
70
+ :implicitlyWait,
71
+ :setScriptTimeout,
72
+ :setTimeout,
73
+ :describeElement,
74
+ :findChildElement, -- sync
75
+ :findChildElements, -- sync
76
+ :clickElement,
77
+ :submitElement,
78
+ :getElementValue,
79
+ :sendKeysToElement,
80
+ :uploadFile,
81
+ :getElementTagName,
82
+ :clearElement,
83
+ :isElementSelected,
84
+ :isElementEnabled,
85
+ :getElementAttribute,
86
+ :elementEquals,
87
+ :isElementDisplayed, -- does not sync
88
+ :getElementLocation,
89
+ :getElementLocationOnceScrolledIntoView,
90
+ :getElementSize,
91
+ :dragElement,
92
+ :getElementValueOfCssProperty,
93
+ :getElementText, -- does not sync
94
+ :getScreenOrientation,
95
+ :setScreenOrientation,
96
+ :click, -- does not sync
97
+ :doubleClick,
98
+ :mouseDown,
99
+ :mouseUp,
100
+ :mouseMoveTo,
101
+ :sendModifierKeyToActiveElement,
102
+ :sendKeysToActiveElement,
103
+ :executeSql,
104
+ :getLocation,
105
+ :setLocation, -- must sync (custom protractor method only, not the selenium setLocation)
106
+ :getAppCache,
107
+ :getAppCacheStatus,
108
+ :clearAppCache,
109
+ :isBrowserOnline,
110
+ :setBrowserOnline,
111
+ :getLocalStorageItem,
112
+ :removeLocalStorageItem,
113
+ :getLocalStorageKeys,
114
+ :setLocalStorageItem,
115
+ :clearLocalStorage,
116
+ :getLocalStorageSize,
117
+ :getSessionStorageItem,
118
+ :removeSessionStorageItem,
119
+ :getSessionStorageKeys,
120
+ :setSessionStorageItem,
121
+ :clearSessionStorage,
122
+ :getSessionStorageSize,
123
+ :imeGetAvailableEngines,
124
+ :imeGetActiveEngine,
125
+ :imeIsActivated,
126
+ :imeDeactivate,
127
+ :imeActivateEngine,
128
+ :touchSingleTap,
129
+ :touchDoubleTap,
130
+ :touchLongPress,
131
+ :touchDown,
132
+ :touchUp,
133
+ :touchMove,
134
+ :touchScroll,
135
+ :touchFlick,
136
+ :getAvailableLogTypes,
137
+ :getLog]
@@ -0,0 +1,121 @@
1
+ var status = element(by.binding('slowHttpStatus'));
2
+
3
+ expect(status.getText()).toEqual('not started');
4
+ expect(status.getText()).toEqual('not started');
5
+ expect(status.getText()).toEqual('not started');
6
+
7
+
8
+ In protractor, the element will be refound before getting the text.
9
+ in Ruby webdriver, the element will be referenced by id (instead of issuing a find command)
10
+ and the text will be retrieved directly.
11
+
12
+
13
+
14
+ ---
15
+
16
+
17
+
18
+
19
+
20
+
21
+ 11:43:37.983 INFO - Executing: [new session: Capabilities [{count=1, browserName=firefox, version=ANY}]])
22
+ 11:43:37.984 INFO - Creating a new session for Capabilities [{count=1, browserName=firefox, version=ANY}]
23
+ 11:43:42.013 INFO - Done: [new session: Capabilities [{count=1, browserName=firefox, version=ANY}]]
24
+ 11:43:42.051 INFO - Executing: [set script timeoutt: 11000])
25
+ 11:43:42.090 INFO - Done: [set script timeoutt: 11000]
26
+ 11:43:42.241 INFO - Executing: [get: data:text/html,<html></html>])
27
+ 11:43:42.330 INFO - Done: [get: data:text/html,<html></html>]
28
+ 11:43:42.341 INFO - Executing: [execute script: window.name = "NG_DEFER_BOOTSTRAP!" + window.name;window.location.replace("http://localhost:8081/index.html#/async");, []])
29
+ 11:43:42.424 INFO - Done: [execute script: window.name = "NG_DEFER_BOOTSTRAP!" + window.name;window.location.replace("http://localhost:8081/index.html#/async");, []]
30
+ 11:43:42.464 INFO - Executing: [execute script: return window.location.href;, []])
31
+ 11:43:42.562 INFO - Done: [execute script: return window.location.href;, []]
32
+ 11:43:42.584 INFO - Executing: [execute async script: try { return (function (attempts, asyncCallback) {
33
+ var callback = function(args) {
34
+ setTimeout(function() {
35
+ asyncCallback(args);
36
+ }, 0);
37
+ };
38
+ var check = function(n) {
39
+ try {
40
+ if (window.angular && window.angular.resumeBootstrap) {
41
+ callback([true, null]);
42
+ } else if (n < 1) {
43
+ if (window.angular) {
44
+ callback([false, 'angular never provided resumeBootstrap']);
45
+ } else {
46
+ callback([false, 'retries looking for angular exceeded']);
47
+ }
48
+ } else {
49
+ window.setTimeout(function() {check(n - 1);}, 1000);
50
+ }
51
+ } catch (e) {
52
+ callback([false, e]);
53
+ }
54
+ };
55
+ check(attempts);
56
+ }).apply(this, arguments); }
57
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [10]])
58
+ 11:43:42.621 INFO - Done: [execute async script: try { return (function (attempts, asyncCallback) {
59
+ var callback = function(args) {
60
+ setTimeout(function() {
61
+ asyncCallback(args);
62
+ }, 0);
63
+ };
64
+ var check = function(n) {
65
+ try {
66
+ if (window.angular && window.angular.resumeBootstrap) {
67
+ callback([true, null]);
68
+ } else if (n < 1) {
69
+ if (window.angular) {
70
+ callback([false, 'angular never provided resumeBootstrap']);
71
+ } else {
72
+ callback([false, 'retries looking for angular exceeded']);
73
+ }
74
+ } else {
75
+ window.setTimeout(function() {check(n - 1);}, 1000);
76
+ }
77
+ } catch (e) {
78
+ callback([false, e]);
79
+ }
80
+ };
81
+ check(attempts);
82
+ }).apply(this, arguments); }
83
+ catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [10]]
84
+ 11:43:42.632 INFO - Executing: [execute script: return (function () {
85
+ angular.module('protractorBaseModule_', []).
86
+ config(['$compileProvider', function($compileProvider) {
87
+ if ($compileProvider.debugInfoEnabled) {
88
+ $compileProvider.debugInfoEnabled(true);
89
+ }
90
+ }]);
91
+ }).apply(null, arguments);, []])
92
+ 11:43:42.677 INFO - Done: [execute script: return (function () {
93
+ angular.module('protractorBaseModule_', []).
94
+ config(['$compileProvider', function($compileProvider) {
95
+ if ($compileProvider.debugInfoEnabled) {
96
+ $compileProvider.debugInfoEnabled(true);
97
+ }
98
+ }]);
99
+ }).apply(null, arguments);, []]
100
+ 11:43:42.690 INFO - Executing: [execute script: angular.resumeBootstrap(arguments[0]);, [[protractorBaseModule_]]])
101
+ 11:43:42.778 INFO - Done: [execute script: angular.resumeBootstrap(arguments[0]);, [[protractorBaseModule_]]]
102
+ 11:43:42.840 INFO - Executing: [waitForAngular, [body]])
103
+ 11:43:42.908 INFO - Done: [waitForAngular, [body]]
104
+ 11:43:42.923 INFO - Executing: [findByBinding, [slowHttpStatus, false, null, body]])
105
+ 11:43:43.019 INFO - Done: [findByBinding, [slowHttpStatus, false, null, body]]
106
+ 11:43:43.032 INFO - Executing: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@8f818cf5 -> unknown locator]])
107
+ 11:43:43.082 INFO - Done: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@8f818cf5 -> unknown locator]]
108
+ 11:43:43.095 INFO - Executing: [waitForAngular, [body]])
109
+ 11:43:43.144 INFO - Done: [waitForAngular, [body]]
110
+ 11:43:43.164 INFO - Executing: [findByBinding, [slowHttpStatus, false, null, body]])
111
+ 11:43:43.220 INFO - Done: [findByBinding, [slowHttpStatus, false, null, body]]
112
+ 11:43:43.258 INFO - Executing: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@8f818cf5 -> unknown locator]])
113
+ 11:43:43.356 INFO - Done: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@8f818cf5 -> unknown locator]]
114
+ 11:43:43.373 INFO - Executing: [waitForAngular, [body]])
115
+ 11:43:43.422 INFO - Done: [waitForAngular, [body]]
116
+ 11:43:43.444 INFO - Executing: [findByBinding, [slowHttpStatus, false, null, body]])
117
+ 11:43:43.497 INFO - Done: [findByBinding, [slowHttpStatus, false, null, body]]
118
+ 11:43:43.511 INFO - Executing: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@8f818cf5 -> unknown locator]])
119
+ 11:43:43.567 INFO - Done: [get text: 0 [org.openqa.selenium.remote.RemoteWebElement@8f818cf5 -> unknown locator]]
120
+ 11:43:43.588 INFO - Executing: [delete session: 85df60d0-1d35-492b-a346-6c1b2cf8725d])
121
+ 11:43:43.697 INFO - Done: [delete session: 85df60d0-1d35-492b-a346-6c1b2cf8725d]