angular_webdriver 0.0.7 → 1.0.0

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.
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]