marta 0.36651 → 0.36788
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -12
- data/example_project/p_object/test_page.rb +11 -25
- data/example_project/spec/p_object/pageobjects/MartaTestPage.json +165 -1
- data/example_project/spec/spec_helper.rb +2 -1
- data/example_project/spec/{watir_test_page_spec.rb → test_page_spec.rb} +3 -0
- data/lib/marta.rb +11 -4
- data/lib/marta/data/custom-xpath.js +8 -1
- data/lib/marta/data/element-confirm.js +9 -1
- data/lib/marta/data/element.js +11 -2
- data/lib/marta/data/for_test.html +1 -1
- data/lib/marta/data/for_test.js +8 -2
- data/lib/marta/data/page.js +7 -2
- data/lib/marta/data/test.html +37 -0
- data/lib/marta/injector.rb +16 -7
- data/lib/marta/marta_app/background.js +1 -0
- data/lib/marta/marta_app/content.js +55 -0
- data/lib/marta/marta_app/manifest.json +16 -0
- data/lib/marta/marta_app/marta_app.crx +0 -0
- data/lib/marta/marta_app/marta_app.pem +28 -0
- data/lib/marta/options_and_paths.rb +84 -6
- data/lib/marta/public_methods.rb +2 -2
- data/lib/marta/server.rb +169 -0
- data/lib/marta/user_values_prework.rb +11 -12
- data/lib/marta/version.rb +1 -1
- data/marta.gemspec +2 -1
- metadata +26 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb9cae36f41b19234de4624d84b15b121e18e2ab
|
4
|
+
data.tar.gz: 58e97be1e74776026c8fee29675be311ca296b3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc0b3343e92ca8298626fbb314c59c6c2acb35504b530fcbfcfcf2af895dba08ee3ad55320b3c221f0f208d9e921460b61e1968f63ab11242673d95d05129768
|
7
|
+
data.tar.gz: 37ca26dde66f8db7652fd7adbde7838abd68403ff3e1eb5a6fd4341f48c1b630780e447101980e6dab82d879b62b54f1ff1ce8048005e6dd63fe9c2793a2f931
|
data/README.md
CHANGED
@@ -87,29 +87,46 @@ your_page.itemprop = "about"
|
|
87
87
|
|
88
88
|
*See couple examples in example_project (Ruby checkbox, item1 and 2 radio buttons)*
|
89
89
|
|
90
|
+
**Q: I want to turn learning mode on\off in the code. How?**
|
91
|
+
|
92
|
+
*A:*
|
93
|
+
```ruby
|
94
|
+
dance_with learn: true or false
|
95
|
+
```
|
96
|
+
*Note: it may not work inside of the previously defined class. In that case use:*
|
97
|
+
```ruby
|
98
|
+
your_page.method_edit('newelementname')
|
99
|
+
```
|
100
|
+
|
90
101
|
**Q: I want to use firefox. How could I?**
|
91
102
|
|
92
103
|
*A: dance_with is accepting parameter :browser like*
|
93
104
|
```ruby
|
94
105
|
dance_with browser: Watir::Browser.new(:firefox)
|
95
106
|
```
|
107
|
+
*Note: If you are using a custom browser learn mode will not work properly. Custom browsers could be used for execution only*
|
96
108
|
|
97
|
-
**Q:
|
109
|
+
**Q: Why firefox(or other browser) cannot be used for learning?**
|
98
110
|
|
99
|
-
*A: Marta
|
100
|
-
```ruby
|
101
|
-
dance_with folder: 'path/to/your/folder'
|
102
|
-
```
|
111
|
+
*A: Marta is starting by default with Chrome with an extension - marta_app. It is for Chrome only. This app is used for dialogs between user and Marta in a learning mode as well as a server.*
|
103
112
|
|
104
|
-
**Q:
|
113
|
+
**Q: A server?**
|
105
114
|
|
106
|
-
*A:*
|
115
|
+
*A: In order to pass security restrictions for js on pages the code injected to the page by marta is sending information to the marta_app. And marta_app is sending information through a web server. You can force Marta to use a specific port:*
|
107
116
|
```ruby
|
108
|
-
dance_with
|
117
|
+
dance_with port: 7766
|
109
118
|
```
|
110
|
-
*Note:
|
119
|
+
*Note: default port is 6260 but now Marta is starting server for each thread. It will be changed in the future. So if the port 6260 is busy, Marta will take next 6261 and then 6262, etc.*
|
120
|
+
|
121
|
+
**Q: What else Marta server and Marta_app can do?**
|
122
|
+
|
123
|
+
*A: Nothing. But I have a nice plan about it.*
|
124
|
+
|
125
|
+
**Q: How Marta stores data?**
|
126
|
+
|
127
|
+
*A: Marta creates a json files in the default folder with name = Marta_s_pageobjects'. You can force Marta to use other folder like*
|
111
128
|
```ruby
|
112
|
-
|
129
|
+
dance_with folder: 'path/to/your/folder'
|
113
130
|
```
|
114
131
|
|
115
132
|
**Q: How is working the open_page method?**
|
@@ -171,6 +188,14 @@ dance_with tolerancy: 1024# is the default value
|
|
171
188
|
dance_with cold_timeout: 5
|
172
189
|
```
|
173
190
|
|
191
|
+
**Q: What if I need Marta to drop all the settings to default?**
|
192
|
+
|
193
|
+
*A: Start Marta with clear setting*
|
194
|
+
```ruby
|
195
|
+
dance_with clear: true
|
196
|
+
```
|
197
|
+
*Note: It will restart browser as well*
|
198
|
+
|
174
199
|
**Q: How can I get Watir browser instance if I want for example execute_script or find element without Marta?**
|
175
200
|
|
176
201
|
*A: Like that*
|
@@ -272,11 +297,11 @@ g_page.search "I am in love with selenium."
|
|
272
297
|
$ cd example_project
|
273
298
|
$ ./tests_with_learning.sh
|
274
299
|
|
275
|
-
*Take a look at elements defining (especially when
|
300
|
+
*Take a look at elements defining (especially when variable #{r_selection} is used). Try to redefine elements. Also take a look at the ruby code. There are some comments.*
|
276
301
|
|
277
302
|
**Q: What else?**
|
278
303
|
|
279
|
-
*A: Nothing. Marta is under development. Her version is 0.
|
304
|
+
*A: Nothing. Marta is under development. Her version is 0.36788. All the necessary features are working already but there are tons of things that should be done. And I am not a professional developer.*
|
280
305
|
|
281
306
|
## Internal Design
|
282
307
|
|
@@ -1,31 +1,17 @@
|
|
1
1
|
# TestPage class will wrap MartaTestPage class generated by Marta
|
2
2
|
# Methods that are not defined here will be taken from class generated by Marta
|
3
3
|
class MyTestPage < MartaTestPage
|
4
|
-
def form_fill(
|
5
|
-
|
6
|
-
|
7
|
-
# name_field is MartaTestPage.name_field.
|
4
|
+
def form_fill(some: 'thing', selection: 'Z', confirmed: true,
|
5
|
+
r_selection: (rand(3)+1).to_s)
|
6
|
+
# some_field is MartaTestPage.some_field.
|
8
7
|
# Marta will ask about it in learning mode
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@lang = language
|
18
|
-
@happy = how_happy
|
19
|
-
@i1 = item1
|
20
|
-
@i2 = item2
|
21
|
-
dropbox.select browser
|
22
|
-
# language_checkbox, how_happy_element, item1_element and item2_element are
|
23
|
-
# defined as dependant of related variables. For example if @lang == 'Java'
|
24
|
-
# language_checkbox will be an element <input... value='Java'>
|
25
|
-
language_checkbox.set
|
26
|
-
how_happy_element.set
|
27
|
-
item1_element.set
|
28
|
-
item2_element.set
|
29
|
-
send_button.click
|
8
|
+
some_field.set some
|
9
|
+
# We will choose radio dynamically. Note:
|
10
|
+
# the variable @r_select is defined at the page creation stage
|
11
|
+
@r_select = r_selection
|
12
|
+
dynamic_radio.set
|
13
|
+
dropbox.select selection
|
14
|
+
dummy_checkbox.set if confirmed
|
15
|
+
first_button.click
|
30
16
|
end
|
31
17
|
end
|
@@ -1 +1,165 @@
|
|
1
|
-
{
|
1
|
+
{
|
2
|
+
"vars": {
|
3
|
+
"path": "test",
|
4
|
+
"r_select": "notdefined",
|
5
|
+
"url": ""
|
6
|
+
},
|
7
|
+
"meths": {
|
8
|
+
"numbers": {
|
9
|
+
"options": {
|
10
|
+
"collection": true,
|
11
|
+
"self": "LI",
|
12
|
+
"not_self": null,
|
13
|
+
"pappy": "UL",
|
14
|
+
"not_pappy": null,
|
15
|
+
"granny": "FORM",
|
16
|
+
"not_granny": null
|
17
|
+
},
|
18
|
+
"not_self": null,
|
19
|
+
"not_pappy": null,
|
20
|
+
"not_granny": null,
|
21
|
+
"self": {
|
22
|
+
"class": [
|
23
|
+
"collection"
|
24
|
+
]
|
25
|
+
},
|
26
|
+
"pappy": {
|
27
|
+
},
|
28
|
+
"granny": {
|
29
|
+
}
|
30
|
+
},
|
31
|
+
"some_field": {
|
32
|
+
"granny": {
|
33
|
+
},
|
34
|
+
"options": {
|
35
|
+
"collection": false,
|
36
|
+
"granny": "BODY",
|
37
|
+
"pappy": "FORM",
|
38
|
+
"self": "INPUT"
|
39
|
+
},
|
40
|
+
"pappy": {
|
41
|
+
},
|
42
|
+
"self": {
|
43
|
+
"class": [
|
44
|
+
"some"
|
45
|
+
],
|
46
|
+
"placeholder": "utka",
|
47
|
+
"type": "text"
|
48
|
+
}
|
49
|
+
},
|
50
|
+
"dynamic_radio": {
|
51
|
+
"granny": {
|
52
|
+
},
|
53
|
+
"options": {
|
54
|
+
"collection": false,
|
55
|
+
"granny": "FORM",
|
56
|
+
"pappy": "DIV",
|
57
|
+
"self": "INPUT"
|
58
|
+
},
|
59
|
+
"pappy": {
|
60
|
+
},
|
61
|
+
"self": {
|
62
|
+
"id": "choice#{@r_select}",
|
63
|
+
"name": "contact",
|
64
|
+
"type": "radio",
|
65
|
+
"value": "#{@r_select}"
|
66
|
+
}
|
67
|
+
},
|
68
|
+
"dropbox": {
|
69
|
+
"granny": {
|
70
|
+
},
|
71
|
+
"options": {
|
72
|
+
"collection": false,
|
73
|
+
"granny": "BODY",
|
74
|
+
"pappy": "FORM",
|
75
|
+
"self": "SELECT"
|
76
|
+
},
|
77
|
+
"pappy": {
|
78
|
+
},
|
79
|
+
"self": {
|
80
|
+
"custom": "custom",
|
81
|
+
"retrieved_by_marta_text": "\n "
|
82
|
+
}
|
83
|
+
},
|
84
|
+
"dummy_checkbox": {
|
85
|
+
"granny": {
|
86
|
+
},
|
87
|
+
"options": {
|
88
|
+
"collection": false,
|
89
|
+
"granny": "FORM",
|
90
|
+
"pappy": "DIV",
|
91
|
+
"self": "INPUT"
|
92
|
+
},
|
93
|
+
"pappy": {
|
94
|
+
},
|
95
|
+
"self": {
|
96
|
+
"name": "checkbox",
|
97
|
+
"type": "checkbox",
|
98
|
+
"value": "checkbox"
|
99
|
+
}
|
100
|
+
},
|
101
|
+
"confirmation_message": {
|
102
|
+
"granny": {
|
103
|
+
},
|
104
|
+
"options": {
|
105
|
+
"collection": false,
|
106
|
+
"granny": "HTML",
|
107
|
+
"pappy": "BODY",
|
108
|
+
"self": "H1"
|
109
|
+
},
|
110
|
+
"pappy": {
|
111
|
+
},
|
112
|
+
"self": {
|
113
|
+
"id": "Title",
|
114
|
+
"retrieved_by_marta_text": "1st button was clicked"
|
115
|
+
}
|
116
|
+
},
|
117
|
+
"second_button": {
|
118
|
+
"granny": {
|
119
|
+
},
|
120
|
+
"options": {
|
121
|
+
"collection": false,
|
122
|
+
"granny": "BODY",
|
123
|
+
"pappy": "FORM",
|
124
|
+
"self": "BUTTON"
|
125
|
+
},
|
126
|
+
"pappy": {
|
127
|
+
},
|
128
|
+
"self": {
|
129
|
+
"retrieved_by_marta_text": "Second button"
|
130
|
+
}
|
131
|
+
},
|
132
|
+
"title": {
|
133
|
+
"granny": {
|
134
|
+
},
|
135
|
+
"options": {
|
136
|
+
"collection": false,
|
137
|
+
"granny": "HTML",
|
138
|
+
"pappy": "BODY",
|
139
|
+
"self": "H1"
|
140
|
+
},
|
141
|
+
"pappy": {
|
142
|
+
},
|
143
|
+
"self": {
|
144
|
+
"id": "Title",
|
145
|
+
"retrieved_by_marta_text": "Test page"
|
146
|
+
}
|
147
|
+
},
|
148
|
+
"first_button": {
|
149
|
+
"granny": {
|
150
|
+
},
|
151
|
+
"options": {
|
152
|
+
"collection": false,
|
153
|
+
"granny": "BODY",
|
154
|
+
"pappy": "FORM",
|
155
|
+
"self": "INPUT"
|
156
|
+
},
|
157
|
+
"pappy": {
|
158
|
+
},
|
159
|
+
"self": {
|
160
|
+
"type": "button",
|
161
|
+
"value": "First button"
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
}
|
@@ -4,8 +4,9 @@ require 'rspec'
|
|
4
4
|
include Marta
|
5
5
|
RSpec.configure do |config|
|
6
6
|
config.before do |example|
|
7
|
+
@port = 7000
|
7
8
|
folder = "./spec/p_object/pageobjects"
|
8
|
-
dance_with(folder: folder)
|
9
|
+
dance_with(folder: folder, port: @port, base_url: "localhost:#{@port}")
|
9
10
|
require 'test_page'
|
10
11
|
end
|
11
12
|
end
|
@@ -5,7 +5,10 @@ describe "We will do some dummy things like" do
|
|
5
5
|
@page = MyTestPage.open_page
|
6
6
|
end
|
7
7
|
it "touching every single element at the test page" do
|
8
|
+
expect(@page.numbers[1].text).to eq "Two"
|
8
9
|
@page.form_fill
|
9
10
|
expect(@page.confirmation_message_exact.present?).to be true
|
11
|
+
@page.second_button.click
|
12
|
+
expect(@page.title_exact.present?).to be true
|
10
13
|
end
|
11
14
|
end
|
data/lib/marta.rb
CHANGED
@@ -12,9 +12,13 @@ require 'marta/black_magic'
|
|
12
12
|
require 'marta/simple_element_finder'
|
13
13
|
require 'marta/x_path'
|
14
14
|
require 'marta/page_arithmetic'
|
15
|
+
require 'marta/server'
|
15
16
|
require "watir"
|
16
17
|
require 'fileutils'
|
17
18
|
require 'json'
|
19
|
+
require 'webrick'
|
20
|
+
require 'socket'
|
21
|
+
|
18
22
|
|
19
23
|
#
|
20
24
|
# Marta class is providing three simple methods.
|
@@ -31,7 +35,7 @@ module Marta
|
|
31
35
|
|
32
36
|
include BlackMagic, XPath, SimpleElementFinder, ClassesCreation,
|
33
37
|
PublicMethods, Dialogs, Injector, Lightning, OptionsAndPaths,
|
34
|
-
Json2Class, ReadWrite, UserValuePrework, PageArithmetic
|
38
|
+
Json2Class, ReadWrite, UserValuePrework, PageArithmetic, Server
|
35
39
|
|
36
40
|
# open_page can create new instance
|
37
41
|
def self.open_page(*args)
|
@@ -62,11 +66,14 @@ module Marta
|
|
62
66
|
# Settings can be changed at any time by calling dance with.
|
63
67
|
# Read more in the README
|
64
68
|
def dance_with(browser: nil, folder: nil, learn: nil, tolerancy: nil,
|
65
|
-
base_url: nil, cold_timeout: nil)
|
66
|
-
SettingMaster.
|
69
|
+
base_url: nil, cold_timeout: nil, port: nil, clear: nil)
|
70
|
+
SettingMaster.clear if clear
|
71
|
+
SettingMaster.set_port port
|
72
|
+
SettingMaster.set_server # server should be before browser
|
73
|
+
SettingMaster.set_engine browser # browser should be before learn!
|
74
|
+
SettingMaster.set_learn learn
|
67
75
|
SettingMaster.set_folder folder
|
68
76
|
SettingMaster.set_base_url base_url
|
69
|
-
SettingMaster.set_learn learn
|
70
77
|
read_folder
|
71
78
|
SettingMaster.set_tolerancy tolerancy
|
72
79
|
SettingMaster.set_cold_timeout cold_timeout
|
@@ -43,6 +43,7 @@ document.marta_confirm = function(){
|
|
43
43
|
var toClear = document.querySelector("[martaclass=marta_smthing]");
|
44
44
|
toClear.parentNode.removeChild(toClear);
|
45
45
|
document.marta_confirm_mark = true;
|
46
|
+
document.marta_connect();
|
46
47
|
};
|
47
48
|
|
48
49
|
document.marta_try_again = function(){
|
@@ -53,6 +54,7 @@ document.marta_try_again = function(){
|
|
53
54
|
toClear.parentNode.removeChild(toClear);
|
54
55
|
document.marta_confirm_mark = true;
|
55
56
|
document.marta_result = "2";
|
57
|
+
document.marta_connect();
|
56
58
|
};
|
57
59
|
|
58
60
|
document.marta_hide = function() {
|
@@ -62,4 +64,9 @@ document.marta_hide = function() {
|
|
62
64
|
} else{
|
63
65
|
toHide.setAttribute("martastyle", "hidden");
|
64
66
|
};
|
65
|
-
}
|
67
|
+
};
|
68
|
+
|
69
|
+
document.marta_connect = function() {
|
70
|
+
var event = new CustomEvent('marta_send', {'detail':{ 'port': document.martaPort, 'mark': document.marta_confirm_mark }});
|
71
|
+
this.dispatchEvent(event);
|
72
|
+
};
|
@@ -11,6 +11,7 @@ document.marta_confirm = function(){
|
|
11
11
|
toClear.parentNode.removeChild(toClear);
|
12
12
|
document.marta_confirm_mark = true;
|
13
13
|
document.marta_result = "4";
|
14
|
+
document.marta_connect();
|
14
15
|
};
|
15
16
|
|
16
17
|
document.marta_click_work = function(e){};
|
@@ -20,6 +21,7 @@ document.marta_try_again = function(){
|
|
20
21
|
toClear.parentNode.removeChild(toClear);
|
21
22
|
document.marta_confirm_mark = true;
|
22
23
|
document.marta_result = "2";
|
24
|
+
document.marta_connect();
|
23
25
|
};
|
24
26
|
|
25
27
|
document.marta_set_by_hand = function(){
|
@@ -27,6 +29,7 @@ document.marta_set_by_hand = function(){
|
|
27
29
|
toClear.parentNode.removeChild(toClear);
|
28
30
|
document.marta_confirm_mark = true;
|
29
31
|
document.marta_result = "3";
|
32
|
+
document.marta_connect();
|
30
33
|
};
|
31
34
|
|
32
35
|
document.marta_add_data = function() {
|
@@ -41,4 +44,9 @@ document.marta_hide = function() {
|
|
41
44
|
} else{
|
42
45
|
toHide.setAttribute("martastyle", "hidden");
|
43
46
|
};
|
44
|
-
}
|
47
|
+
};
|
48
|
+
|
49
|
+
document.marta_connect = function() {
|
50
|
+
var event = new CustomEvent('marta_send', {'detail':{ 'port': document.martaPort, 'mark': document.marta_confirm_mark }});
|
51
|
+
this.dispatchEvent(event);
|
52
|
+
};
|
data/lib/marta/data/element.js
CHANGED
@@ -85,7 +85,8 @@ document.marta_add_field = function(title, what, key, marker) {
|
|
85
85
|
document.getElementById("marta_default_value"+document.marta_room).onchange = function(e) {document.marta_change_field(e)};
|
86
86
|
};
|
87
87
|
|
88
|
-
document.marta_change_field = function(
|
88
|
+
document.marta_change_field = function(event){
|
89
|
+
var field = event.target;
|
89
90
|
var data = field.getAttribute("marta_object_map").split(";;");
|
90
91
|
if (data[2] == "-1"){
|
91
92
|
if (field.value == ""){
|
@@ -134,6 +135,7 @@ document.marta_confirm = function(){
|
|
134
135
|
};
|
135
136
|
};
|
136
137
|
document.marta_confirm_mark = true;
|
138
|
+
document.marta_connect();
|
137
139
|
return document.marta_result;
|
138
140
|
};
|
139
141
|
};
|
@@ -300,6 +302,7 @@ document.marta_set_by_hand = function(){
|
|
300
302
|
toClear.parentNode.removeChild(toClear);
|
301
303
|
document.marta_confirm_mark = true;
|
302
304
|
document.marta_result = "3";
|
305
|
+
document.marta_connect();
|
303
306
|
};
|
304
307
|
|
305
308
|
document.marta_end_loop = function(){
|
@@ -307,6 +310,7 @@ document.marta_end_loop = function(){
|
|
307
310
|
document.marta_clean_up();
|
308
311
|
document.marta_confirm_mark = true;
|
309
312
|
document.marta_result = "1";
|
313
|
+
document.marta_connect();
|
310
314
|
}
|
311
315
|
};
|
312
316
|
|
@@ -317,4 +321,9 @@ document.marta_hide = function() {
|
|
317
321
|
} else{
|
318
322
|
toHide.setAttribute("martastyle", "hidden");
|
319
323
|
};
|
320
|
-
}
|
324
|
+
};
|
325
|
+
|
326
|
+
document.marta_connect = function() {
|
327
|
+
var event = new CustomEvent('marta_send', {'detail':{ 'port': document.martaPort, 'mark': document.marta_confirm_mark }});
|
328
|
+
this.dispatchEvent(event);
|
329
|
+
};
|
data/lib/marta/data/for_test.js
CHANGED
@@ -4,5 +4,11 @@ document.marta_add_data = function(){
|
|
4
4
|
};
|
5
5
|
document.marta_result = "";
|
6
6
|
document.marta_confirm_mark = false;
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
document.marta_connect = function() {
|
9
|
+
var event = new CustomEvent('marta_send', {'detail':{ 'port': document.martaPort, 'mark': document.marta_confirm_mark }});
|
10
|
+
this.dispatchEvent(event);
|
11
|
+
};
|
12
|
+
|
13
|
+
setTimeout(function() { document.marta_result = "Done"; document.marta_connect(); }, 1000);
|
14
|
+
setTimeout(function() { document.marta_confirm_mark = true; document.marta_connect(); }, 2000);
|
data/lib/marta/data/page.js
CHANGED
@@ -37,6 +37,7 @@ document.marta_confirm = function(){
|
|
37
37
|
var toClear = document.querySelector("[martaclass=marta_div]");
|
38
38
|
toClear.parentNode.removeChild(toClear);
|
39
39
|
document.marta_confirm_mark = true;
|
40
|
+
document.marta_connect();
|
40
41
|
return document.marta_result;};
|
41
42
|
|
42
43
|
document.marta_add_data = function() {
|
@@ -57,7 +58,6 @@ document.marta_add_data = function() {
|
|
57
58
|
document.marta_delete_line = function(theEvent) {
|
58
59
|
var line = theEvent.target.getAttribute("martaroom");
|
59
60
|
var staff = document.getElementById("marta_staff"+line);
|
60
|
-
title.parentNode.removeChild(title);
|
61
61
|
staff.parentNode.removeChild(staff);
|
62
62
|
};
|
63
63
|
|
@@ -68,4 +68,9 @@ document.marta_hide = function() {
|
|
68
68
|
} else{
|
69
69
|
toHide.setAttribute("martastyle", "hidden");
|
70
70
|
};
|
71
|
-
}
|
71
|
+
};
|
72
|
+
|
73
|
+
document.marta_connect = function() {
|
74
|
+
var event = new CustomEvent('marta_send', {'detail':{ 'port': document.martaPort, 'mark': document.marta_confirm_mark }});
|
75
|
+
this.dispatchEvent(event);
|
76
|
+
};
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<html>
|
2
|
+
<title>Example page</title>
|
3
|
+
<body>
|
4
|
+
<h1 id='Title'>Test page</h1>
|
5
|
+
<form>
|
6
|
+
<input type='text' class='some' placeholder='utka'>
|
7
|
+
<select custom='custom'>
|
8
|
+
<option value="A">A</option>
|
9
|
+
<option value="B">B</option>
|
10
|
+
<option value="C">C</option>
|
11
|
+
<option value="Z">Z</option>
|
12
|
+
</select>
|
13
|
+
<p>Select something:</p>
|
14
|
+
<div>
|
15
|
+
<input type="radio" id="choice1" name="contact" value="1">
|
16
|
+
<label for="choice1">Apple</label>
|
17
|
+
|
18
|
+
<input type="radio" id="choice2" name="contact" value="2">
|
19
|
+
<label for="choice2">Peach</label>
|
20
|
+
|
21
|
+
<input type="radio" id="choice3" name="contact" value="3">
|
22
|
+
<label for="choice3">Something</label>
|
23
|
+
</div>
|
24
|
+
<div>
|
25
|
+
<input type="checkbox" name="checkbox" value="checkbox">
|
26
|
+
<label for="checkbox">Select checkbox.</label>
|
27
|
+
</div>
|
28
|
+
<ul>
|
29
|
+
<li class='collection'>One</li>
|
30
|
+
<li class='collection'>Two</li>
|
31
|
+
<li class='collection'>Three</li>
|
32
|
+
</ul>
|
33
|
+
<input type='button' value='First button' onclick='document.getElementById("Title").innerHTML = "1st button was clicked"'></input>
|
34
|
+
<button >Second button</button>
|
35
|
+
</form>
|
36
|
+
</body>
|
37
|
+
</html>
|
data/lib/marta/injector.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'marta/server'
|
2
|
+
require 'marta/options_and_paths'
|
3
|
+
|
1
4
|
module Marta
|
2
5
|
|
3
6
|
#
|
@@ -7,6 +10,8 @@ module Marta
|
|
7
10
|
# Those insertions are the only way for her to perform dialog with user
|
8
11
|
module Injector
|
9
12
|
|
13
|
+
include Server, OptionsAndPaths
|
14
|
+
|
10
15
|
private
|
11
16
|
|
12
17
|
#
|
@@ -15,6 +20,8 @@ module Marta
|
|
15
20
|
# @note It is believed that no user will use it
|
16
21
|
class Syringe
|
17
22
|
|
23
|
+
include Server, OptionsAndPaths
|
24
|
+
|
18
25
|
def initialize(engine, marta_what, title = 'Something important',
|
19
26
|
old_data = Hash.new, folder = gem_libdir,
|
20
27
|
custom_vars = Array.new, custom_scripts = Array.new)
|
@@ -27,8 +34,10 @@ module Marta
|
|
27
34
|
@custom_vars = custom_vars
|
28
35
|
@custom_scripts = custom_scripts
|
29
36
|
@default_vars = [{"marta_what": "\"#{@title}\""},
|
30
|
-
{"old_marta_Data": @data.to_s.gsub('=>',':').gsub('nil','null')}
|
31
|
-
|
37
|
+
{"old_marta_Data": @data.to_s.gsub('=>',':').gsub('nil','null')},
|
38
|
+
{"martaPort": SettingMaster.port.to_s}]
|
39
|
+
@default_scripts =
|
40
|
+
["document.marta_add_data(); document.marta_connect();"]
|
32
41
|
end
|
33
42
|
|
34
43
|
# "first" or "last".
|
@@ -49,7 +58,7 @@ module Marta
|
|
49
58
|
else
|
50
59
|
script = inner
|
51
60
|
end
|
52
|
-
|
61
|
+
run_script(script)
|
53
62
|
end
|
54
63
|
|
55
64
|
# Taking a correct js file to inject
|
@@ -81,7 +90,7 @@ module Marta
|
|
81
90
|
|
82
91
|
# Syringe runs scripts
|
83
92
|
def run_script(script)
|
84
|
-
@engine.execute_script(
|
93
|
+
@engine.execute_script script.gsub("\n",'')
|
85
94
|
end
|
86
95
|
|
87
96
|
# Syringe takes array of hashes to set lots of variables
|
@@ -115,10 +124,10 @@ module Marta
|
|
115
124
|
result = false
|
116
125
|
while result != true
|
117
126
|
# When Marta can't get a result she is reinjecting her stuff
|
118
|
-
result =
|
119
|
-
actual_injection if result
|
127
|
+
result = MartaServer.wait_user_dialog_response
|
128
|
+
actual_injection if !result
|
120
129
|
end
|
121
|
-
|
130
|
+
run_script("return document.marta_result")
|
122
131
|
end
|
123
132
|
end
|
124
133
|
|
@@ -0,0 +1 @@
|
|
1
|
+
// Nothing here now
|
@@ -0,0 +1,55 @@
|
|
1
|
+
var port = 6260;
|
2
|
+
|
3
|
+
async function port_set(value){
|
4
|
+
await chrome.storage.sync.set({port: value}, function() {
|
5
|
+
console.log('Value is set to ' + value);
|
6
|
+
});
|
7
|
+
};
|
8
|
+
|
9
|
+
async function port_get(){
|
10
|
+
await chrome.storage.sync.get(['port'], function(result) {
|
11
|
+
port = result.port;
|
12
|
+
console.log('The port currently is ' + port);
|
13
|
+
});
|
14
|
+
};
|
15
|
+
|
16
|
+
document.addEventListener("marta_send", async function(e) {
|
17
|
+
console.log("User is saying smthing to Marta");
|
18
|
+
if (typeof e.detail.port !== "undefined"){
|
19
|
+
await port_set(e.detail.port)
|
20
|
+
await port_get();
|
21
|
+
};
|
22
|
+
//console.log(port);
|
23
|
+
//console.log(e.detail.port);
|
24
|
+
console.log("Marta is acting back. With port = " + port);
|
25
|
+
marta_real_send(e.detail.mark, port);
|
26
|
+
});
|
27
|
+
|
28
|
+
function marta_real_send(answer, the_port) {
|
29
|
+
if (answer == true) {
|
30
|
+
console.log("Marta js is calling Marta ruby");
|
31
|
+
document.xmlHttp = new XMLHttpRequest();
|
32
|
+
var martaUrl = "http://localhost:" + the_port + "/dialog/got_answer";
|
33
|
+
document.xmlHttp.open( "GET", martaUrl, false );
|
34
|
+
document.xmlHttp.send( null );
|
35
|
+
};
|
36
|
+
return port;
|
37
|
+
};
|
38
|
+
|
39
|
+
async function refreshData()
|
40
|
+
{ console.log("Marta is checking is she on the page");
|
41
|
+
|
42
|
+
if ((typeof document.getElementById("marta_s_everything") == undefined) || (document.getElementById("marta_s_everything") == null)){
|
43
|
+
console.log("Marta is lost. Asking ruby Marta to do something with the port = " + port);
|
44
|
+
document.xmlHttp = new XMLHttpRequest();
|
45
|
+
var martaUrl = "http://localhost:" + port + "/dialog/not_answer";
|
46
|
+
try {document.xmlHttp.open( "GET", martaUrl, false );
|
47
|
+
document.xmlHttp.send( null );
|
48
|
+
} catch {
|
49
|
+
console.log("Cannot connect with port = " + port);
|
50
|
+
}
|
51
|
+
} else {
|
52
|
+
};
|
53
|
+
}
|
54
|
+
|
55
|
+
setInterval(async function(){await port_get(); await refreshData()},1000);
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"name": "Marta app",
|
3
|
+
"version": "0.36788",
|
4
|
+
"description": "Messaging from browser to main app",
|
5
|
+
"permissions": ["activeTab", "http://127.0.0.1*/*", "storage"],
|
6
|
+
"background": {
|
7
|
+
"scripts": ["background.js"],
|
8
|
+
"persistent": true
|
9
|
+
},
|
10
|
+
"content_scripts": [{
|
11
|
+
"matches": ["<all_urls>"],
|
12
|
+
"all_frames": true,
|
13
|
+
"js": ["content.js"]
|
14
|
+
}],
|
15
|
+
"manifest_version": 2
|
16
|
+
}
|
Binary file
|
@@ -0,0 +1,28 @@
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
2
|
+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDxrXsFaSILL75W
|
3
|
+
2axSD/fW9nxcvP/jxBgcmbG58oguJ5QVAI45ay0wOBa3z860BDRmYY2ICi8hjIXi
|
4
|
+
wmlUG3KY8p13pV9oMkWAbi69Z4s+osELP7XYir4BVxjYeU7KTqhsWIh3Cg3DBpMl
|
5
|
+
j98wzgSPxKW/NaUrInaZjYhW2ZYg9wrjNyc6LRm9Tkl6sPPGRFSSn8c9FxBwq8CT
|
6
|
+
2e/x4QsicjkUWbKawIPvb3C4zmyc9QsZlWt3T9yd7ra17FGHBy+6Womvw6d3pmdK
|
7
|
+
HF+rjY1ldjmQ/E6GMJeE1sfdc2uwh1LYoGM9vJXx8NVKNHWREthHrOa7KkEyrsNw
|
8
|
+
AFp8sIgvAgMBAAECggEAK07LHM0aLKcBlM6s8oeqAftpjbTQpiAdsgJYttmfTaYK
|
9
|
+
Azl2QxPRpTJn38h9YgTe3vncQuSQTZLA60GrXkcM4huX3DjmP+XCTqFv/sDvUuoX
|
10
|
+
bcyc6ZDzO4pACYqzc81koQW8bph+ntQuyixd8oD4kErM6NbUIkaquhmCtQ2IuZ8y
|
11
|
+
RsEV9Dn0ZAo5o0X5IZKiXVeRGUymvN9eNcdzLVMomgCBBwFVe7avo4ADivXrQLlY
|
12
|
+
CZufCoZO5i/67S4YvbgQqEiBInHLAsAC9JmXzwGcpw/48glahl/YzhZ4lQbGNEHc
|
13
|
+
7H13D/ZBna4dvX4Mn/rW+XtiRZIxVAvgo1y8xi3dAQKBgQD/aesE2/1CW+uzNU9q
|
14
|
+
ji1438YHEkkPnjdL1cBgopT68aAalp5WI2aqCZOsTztKExtH/SWnzz64pWUI+ZuG
|
15
|
+
Z/c6PZjTXlpPYTsa9hOFroa1QQ3p7HhE7yilzUw/QA03XRc1zPTbxVSxADyf9OlQ
|
16
|
+
2DWBAT77GLX13bMzBmCKbIWM/QKBgQDyO327XSR+I1ViW7YEhUK3xoOjMzlsvAAS
|
17
|
+
n/teueJBbgGpI7Jen4shLKrJDlapXoCiQxIat0vgu+AmeSeCUZ3x/fO69lFVjBB+
|
18
|
+
GjaegmbaC7fU1JiwqJeoK7LYlQrt+17/b4qqwKkUo+7m9G0aTUeQuoUINpX5lTfM
|
19
|
+
xFzYXsJHmwKBgH8E3av8+2YU8JKe4G/NZS/HmWPK5CqwNC+yjYmBUTW7FDQk03lj
|
20
|
+
AZtuR9JZVNLxzY9vhVp+5mJNXoGoIIAnE/wSxf3X3nG7mPk/h1XkBXn+cDz1LJqb
|
21
|
+
lUtfXZvW7rupv/ExjFP/Pq8Hvx6NXbqmy3TsebXGBDfRmVy2vywX7BLBAoGAJ1wl
|
22
|
+
VQGQgXKKWD4guGFS8vutviH/rbxqopweQ0kfC5Stbmdff2KbP9u7MIpE6KZzbmpJ
|
23
|
+
kc/A45aDmJzNH67VZFHofbOyiZ0FvQfTYjQ8NCf9Sfb1jJcIdYoMOIcXTI4w5H6i
|
24
|
+
YJaHotP0aNDEvaZa/5hfL3N3MSPe+kXZ9EqJdQsCgYEAqP+PlqfyZhY2Qlhc0bz9
|
25
|
+
mbQjL3KfF3dN2Qa/vJSylaXDm9lULtVKeQYoTM71zk0D2LhZQlS5PicDN/dbbuIZ
|
26
|
+
mL0bJaZ25uT8Ssus5OK1xxjMHlvzkwNGDjWCw6QJHzO6LzgriFK9CYiRXjXCrZ6b
|
27
|
+
cdd8rjqXXTJG/hAtIDzk+Y4=
|
28
|
+
-----END PRIVATE KEY-----
|
@@ -13,12 +13,34 @@ module Marta
|
|
13
13
|
#
|
14
14
|
# @note It is believed that no user will use it
|
15
15
|
class SettingMaster
|
16
|
+
|
16
17
|
@@folder = Hash.new
|
17
18
|
@@tolerancy = Hash.new
|
18
19
|
@@learn = Hash.new
|
19
20
|
@@engine = Hash.new
|
20
21
|
@@base_url = Hash.new
|
21
22
|
@@cold_timeout = Hash.new
|
23
|
+
@@port = Hash.new
|
24
|
+
@@server = Hash.new
|
25
|
+
|
26
|
+
def self.clear
|
27
|
+
@@folder[thread_id] = nil
|
28
|
+
@@tolerancy[thread_id] = nil
|
29
|
+
@@learn[thread_id] = nil
|
30
|
+
if @@engine[thread_id].class == Watir::Browser
|
31
|
+
@@engine[thread_id].quit
|
32
|
+
end
|
33
|
+
@@engine[thread_id] = nil
|
34
|
+
@@base_url[thread_id] = nil
|
35
|
+
@@cold_timeout[thread_id] = nil
|
36
|
+
@@port[thread_id]
|
37
|
+
@@port[thread_id] = nil
|
38
|
+
@@server[thread_id]
|
39
|
+
if @@server[thread_id].class == Marta::Server::MartaServer
|
40
|
+
@@server[thread_id].server_kill
|
41
|
+
end
|
42
|
+
@@server[thread_id] = nil
|
43
|
+
end
|
22
44
|
|
23
45
|
# Getting uniq id for process thread
|
24
46
|
def self.thread_id
|
@@ -64,6 +86,16 @@ module Marta
|
|
64
86
|
@@cold_timeout[thread_id]
|
65
87
|
end
|
66
88
|
|
89
|
+
# Marta knows the server port.
|
90
|
+
def self.port
|
91
|
+
@@port[thread_id]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Marta stores the server as a setting.
|
95
|
+
def self.server
|
96
|
+
@@server[thread_id]
|
97
|
+
end
|
98
|
+
|
67
99
|
# Marta is changing parameters by the same scheme.
|
68
100
|
def self.parameter_set(what, value, default)
|
69
101
|
what[thread_id] = !value.nil? ? value : what[thread_id]
|
@@ -94,13 +126,16 @@ module Marta
|
|
94
126
|
if (engine.class == Watir::Browser) and
|
95
127
|
(value.class == Watir::Browser) and
|
96
128
|
(engine != value)
|
97
|
-
engine.
|
129
|
+
engine.quit if engine.exists?
|
98
130
|
end
|
99
131
|
iframe_locate
|
100
132
|
@@engine = parameter_set(@@engine, value, nil)
|
101
133
|
iframe_switch_to
|
102
134
|
if engine.nil?
|
103
|
-
|
135
|
+
browser = Watir::Browser.new(:chrome,
|
136
|
+
switches: ["--load-extension=#{gem_libdir}/marta_app"])
|
137
|
+
browser.goto "127.0.0.1:#{SettingMaster.port}/welcome"
|
138
|
+
@@engine = parameter_set(@@engine, value, browser)
|
104
139
|
end
|
105
140
|
end
|
106
141
|
|
@@ -112,6 +147,7 @@ module Marta
|
|
112
147
|
# Marta uses simple rules to set the laearn mode
|
113
148
|
def self.set_learn(value)
|
114
149
|
@@learn = parameter_set(@@learn, value, learn_option)
|
150
|
+
warn "If browser was not started by Marta. Learn will not work properly"
|
115
151
|
end
|
116
152
|
|
117
153
|
# Marta uses simple rules to set the tolerancy value
|
@@ -137,15 +173,41 @@ module Marta
|
|
137
173
|
def self.set_cold_timeout(value)
|
138
174
|
parameter_check_and_set(@@cold_timeout, value, 10, Fixnum)
|
139
175
|
end
|
176
|
+
|
177
|
+
# Marta sets port. If it is not defined and there are number of threads
|
178
|
+
# Marta will use ports from 6260 one by one (6260, 6261, 6262,...)
|
179
|
+
def self.set_port(value)
|
180
|
+
i = 0
|
181
|
+
if value.nil?
|
182
|
+
while Server::MartaServer.port_check(6260 + @@port.size + i)
|
183
|
+
i += 1
|
184
|
+
end
|
185
|
+
end
|
186
|
+
parameter_check_and_set(@@port, value, 6260 + @@port.size + i, Fixnum)
|
187
|
+
end
|
188
|
+
|
189
|
+
# We are storaging server instance as a setting
|
190
|
+
def self.set_server
|
191
|
+
if SettingMaster.server.nil?
|
192
|
+
@@server[thread_id] = Server::MartaServer.new(SettingMaster.port)
|
193
|
+
elsif SettingMaster.server.current_port != SettingMaster.port
|
194
|
+
@@server[thread_id] = Server::MartaServer.new(SettingMaster.port)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Marta knows where is she actually is.
|
199
|
+
def self.gem_libdir
|
200
|
+
t = ["#{Dir.pwd}/lib/#{Marta::NAME}",
|
201
|
+
"#{Gem.dir}/gems/#{Marta::NAME}-#{Marta::VERSION}/lib/#{Marta::NAME}"]
|
202
|
+
File.readable?(t[0])? t[0] : t[1]
|
203
|
+
end
|
140
204
|
end
|
141
205
|
|
142
206
|
private
|
143
207
|
|
144
208
|
# Defining the place for files to inject to browser
|
145
209
|
def gem_libdir
|
146
|
-
|
147
|
-
"#{Gem.dir}/gems/#{Marta::NAME}-#{Marta::VERSION}/lib/#{Marta::NAME}"]
|
148
|
-
File.readable?(t[0])? t[0] : t[1]
|
210
|
+
SettingMaster.gem_libdir
|
149
211
|
end
|
150
212
|
|
151
213
|
# Marta knows does she learn or not.
|
@@ -163,13 +225,29 @@ module Marta
|
|
163
225
|
SettingMaster.tolerancy_value
|
164
226
|
end
|
165
227
|
|
166
|
-
# Marta knows the basic url of the
|
228
|
+
# Marta knows the basic url of the project. If it is defined
|
167
229
|
def base_url
|
168
230
|
SettingMaster.base_url
|
169
231
|
end
|
170
232
|
|
233
|
+
# Marta stores a cold_timeout value
|
171
234
|
def cold_timeout
|
172
235
|
SettingMaster.cold_timeout
|
173
236
|
end
|
237
|
+
|
238
|
+
#Marta stores port for Marta server for each thread.
|
239
|
+
def port
|
240
|
+
SettingMaster.port
|
241
|
+
end
|
242
|
+
|
243
|
+
# Marta can call server easily
|
244
|
+
def server
|
245
|
+
SettingMaster.server
|
246
|
+
end
|
247
|
+
|
248
|
+
# Marta knows was the browser started by she
|
249
|
+
def correct_engine?
|
250
|
+
SettingMaster.correct_engine?
|
251
|
+
end
|
174
252
|
end
|
175
253
|
end
|
data/lib/marta/public_methods.rb
CHANGED
@@ -63,10 +63,10 @@ module Marta
|
|
63
63
|
@path ||= ""
|
64
64
|
if !url.nil?
|
65
65
|
engine.goto url
|
66
|
-
elsif !@url.nil?
|
66
|
+
elsif !@url.nil? and @url != ""
|
67
67
|
engine.goto @url
|
68
68
|
elsif base_url != ""
|
69
|
-
engine.goto base_url +
|
69
|
+
engine.goto base_url + ((@path == "") ? "" : "/#{@path}")
|
70
70
|
else
|
71
71
|
raise ArgumentError, "You should set url to use open_page. You may"\
|
72
72
|
" also use base_url option for dance_with and path for page object"
|
data/lib/marta/server.rb
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
require 'marta/options_and_paths'
|
3
|
+
|
4
|
+
module Marta
|
5
|
+
|
6
|
+
#
|
7
|
+
# Marta's server is an interface that will make Marta more interactive.
|
8
|
+
#
|
9
|
+
# Marta's server is a new way for Marta to communicate with the world.
|
10
|
+
# Right now it will be responsible for dialog operations only.
|
11
|
+
module Server
|
12
|
+
|
13
|
+
include OptionsAndPaths
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
#
|
18
|
+
# Special class is used for storing internal variables of the server
|
19
|
+
#
|
20
|
+
# @note It is believed that no user will use it
|
21
|
+
class ServerStore
|
22
|
+
|
23
|
+
# Getting info about dialog state
|
24
|
+
def self.has_answer
|
25
|
+
@@has_answer
|
26
|
+
end
|
27
|
+
|
28
|
+
# Setting info about the dialog state.
|
29
|
+
def self.has_answer=(value)
|
30
|
+
@@has_answer = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Servlet to be used to understand is dialog answer provided or not
|
36
|
+
#
|
37
|
+
# @note It is believed that no user will use it
|
38
|
+
class DialogServlet < WEBrick::HTTPServlet::AbstractServlet
|
39
|
+
|
40
|
+
# What our server will do on get request
|
41
|
+
def do_GET (request, response)
|
42
|
+
ServerStore.has_answer = nil
|
43
|
+
response.status = 200
|
44
|
+
response.content_type = "text/plain"
|
45
|
+
ServerStore.has_answer = case request.path
|
46
|
+
when '/dialog/got_answer'
|
47
|
+
true
|
48
|
+
when '/dialog/not_answer'
|
49
|
+
false
|
50
|
+
end
|
51
|
+
response.body = "#{Thread.current.object_id}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Welcome Servlet
|
57
|
+
#
|
58
|
+
# @note It is believed that no user will use it
|
59
|
+
class WelcomeServlet < WEBrick::HTTPServlet::AbstractServlet
|
60
|
+
def do_GET (request, response)
|
61
|
+
response.status = 200
|
62
|
+
response.content_type = "text/html"
|
63
|
+
response.body = "<html><body><h1>Welcome!</h1></hr><h2>If You can "\
|
64
|
+
"see this label most probably Marta is working. I hope.</h2></hr>"\
|
65
|
+
"<a href='https://github.com/sseleznevqa/marta'>GITHUB link</a>"\
|
66
|
+
"</body></html>"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Test servlet. For example
|
72
|
+
#
|
73
|
+
# @note It is believed that no user will use it
|
74
|
+
class TestServlet < WEBrick::HTTPServlet::AbstractServlet
|
75
|
+
def do_GET (request, response)
|
76
|
+
response.status = 200
|
77
|
+
response.content_type = "text/html"
|
78
|
+
response.body = File.read(gem_libdir + "/data/test.html")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Server control and logic is in the class.
|
84
|
+
#
|
85
|
+
# @note It is believed that no user will use it
|
86
|
+
class MartaServer
|
87
|
+
|
88
|
+
include OptionsAndPaths
|
89
|
+
|
90
|
+
def initialize(port = SettingMaster.port)
|
91
|
+
@port = port
|
92
|
+
@@thread = Thread.new(port) do |port|
|
93
|
+
begin
|
94
|
+
the_server_start(port)
|
95
|
+
rescue
|
96
|
+
raise RuntimeError, "Could not start the server!"
|
97
|
+
@@thread.kill
|
98
|
+
end
|
99
|
+
end
|
100
|
+
MartaServer.server_check
|
101
|
+
end
|
102
|
+
|
103
|
+
# Here we will store the thread where server is living
|
104
|
+
def self.thread
|
105
|
+
@@thread
|
106
|
+
end
|
107
|
+
|
108
|
+
# Server is starting with mounts.
|
109
|
+
def the_server_start(port)
|
110
|
+
the_server = WEBrick::HTTPServer.new(Port: port,
|
111
|
+
Logger: WEBrick::Log.new(File.open(File::NULL, 'w')),
|
112
|
+
AccessLog: WEBrick::Log.new(File.open(File::NULL, 'w')))
|
113
|
+
the_server.mount "/dialog", DialogServlet
|
114
|
+
the_server.mount "/welcome", WelcomeServlet
|
115
|
+
the_server.mount "/test", TestServlet
|
116
|
+
the_server.mount_proc('/q') {|req, resp| the_server.shutdown; exit;}
|
117
|
+
the_server.start
|
118
|
+
end
|
119
|
+
|
120
|
+
# Marta knows when server is not okay
|
121
|
+
def self.server_check
|
122
|
+
if !@@thread.alive?
|
123
|
+
warn "Marta server was not working properly"
|
124
|
+
@@thread.join
|
125
|
+
else
|
126
|
+
true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.port_check(port)
|
131
|
+
Timeout::timeout(1) do
|
132
|
+
begin
|
133
|
+
TCPSocket.new('127.0.0.1', port).close
|
134
|
+
true
|
135
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
136
|
+
false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
rescue Timeout::Error
|
140
|
+
false
|
141
|
+
end
|
142
|
+
|
143
|
+
# There is a possibility to get the port of the server outside
|
144
|
+
def current_port
|
145
|
+
@port
|
146
|
+
end
|
147
|
+
|
148
|
+
# We are killing the server sometimes
|
149
|
+
def server_kill
|
150
|
+
# So nasty. But WEBrick knows what to do.
|
151
|
+
while @@thread.alive?
|
152
|
+
@@thread.exit
|
153
|
+
end
|
154
|
+
@@thread.join
|
155
|
+
end
|
156
|
+
|
157
|
+
# Server can wait for while somebody will touch it
|
158
|
+
def self.wait_user_dialog_response(wait_time = 600)
|
159
|
+
ServerStore.has_answer = nil
|
160
|
+
server_check
|
161
|
+
start_time = Time.now
|
162
|
+
while ServerStore.has_answer.nil? and (Time.now - start_time < wait_time)
|
163
|
+
# No idea what Am I doing here...
|
164
|
+
end
|
165
|
+
ServerStore.has_answer
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -7,20 +7,19 @@ module Marta
|
|
7
7
|
|
8
8
|
# Marta can parse strings like "hello #{value}"
|
9
9
|
def process_string(str='', requestor = self)
|
10
|
-
|
11
|
-
|
12
|
-
while
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
last_part
|
10
|
+
str ||= ""
|
11
|
+
n = nil
|
12
|
+
while str != n
|
13
|
+
str = n if !n.nil?
|
14
|
+
thevar = str.match(/\#{@+[^\#{@]*}/).to_s
|
15
|
+
if thevar != ""
|
16
|
+
value = requestor.instance_variable_get thevar.match(/@.*[^}]/).to_s
|
17
|
+
n = str.gsub(thevar, value)
|
18
|
+
else
|
19
|
+
n = str
|
21
20
|
end
|
22
21
|
end
|
23
|
-
str
|
22
|
+
str
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
data/lib/marta/version.rb
CHANGED
data/marta.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rake"
|
24
24
|
spec.add_development_dependency "rspec"
|
25
25
|
spec.add_development_dependency "simplecov"
|
26
|
-
spec.add_dependency "watir", '
|
26
|
+
spec.add_dependency "watir", '>= 6.7.2'
|
27
27
|
spec.add_dependency "json"
|
28
|
+
spec.add_dependency "webrick"
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.36788'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergei Seleznev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,14 +70,14 @@ dependencies:
|
|
70
70
|
name: watir
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 6.7.2
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 6.7.2
|
83
83
|
- !ruby/object:Gem::Dependency
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webrick
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: Element location tool for your watir autotests.
|
98
112
|
email:
|
99
113
|
- s_seleznev_qa@hotmail.com
|
@@ -114,7 +128,7 @@ files:
|
|
114
128
|
- example_project/p_object/test_page.rb
|
115
129
|
- example_project/spec/p_object/pageobjects/MartaTestPage.json
|
116
130
|
- example_project/spec/spec_helper.rb
|
117
|
-
- example_project/spec/
|
131
|
+
- example_project/spec/test_page_spec.rb
|
118
132
|
- example_project/tests_with_learning.sh
|
119
133
|
- example_project/tests_without_learning.sh
|
120
134
|
- lib/marta.rb
|
@@ -131,14 +145,21 @@ files:
|
|
131
145
|
- lib/marta/data/page.html
|
132
146
|
- lib/marta/data/page.js
|
133
147
|
- lib/marta/data/style.css
|
148
|
+
- lib/marta/data/test.html
|
134
149
|
- lib/marta/dialogs.rb
|
135
150
|
- lib/marta/injector.rb
|
136
151
|
- lib/marta/json_2_class.rb
|
137
152
|
- lib/marta/lightning.rb
|
153
|
+
- lib/marta/marta_app/background.js
|
154
|
+
- lib/marta/marta_app/content.js
|
155
|
+
- lib/marta/marta_app/manifest.json
|
156
|
+
- lib/marta/marta_app/marta_app.crx
|
157
|
+
- lib/marta/marta_app/marta_app.pem
|
138
158
|
- lib/marta/options_and_paths.rb
|
139
159
|
- lib/marta/page_arithmetic.rb
|
140
160
|
- lib/marta/public_methods.rb
|
141
161
|
- lib/marta/read_write.rb
|
162
|
+
- lib/marta/server.rb
|
142
163
|
- lib/marta/simple_element_finder.rb
|
143
164
|
- lib/marta/user_values_prework.rb
|
144
165
|
- lib/marta/version.rb
|