forked from os-autoinst/openQA
/
12-needle-edit.t
307 lines (246 loc) · 13.1 KB
/
12-needle-edit.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# Copyright (C) 2014-2016 SUSE LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
BEGIN {
unshift @INC, 'lib';
}
use Mojo::Base -strict;
use Test::More;
use Test::Mojo;
use Test::Warnings ':all';
use OpenQA::Test::Case;
use File::Path qw/make_path remove_tree/;
use POSIX qw/strftime/;
use JSON;
use OpenQA::IPC;
use OpenQA::WebSockets;
use OpenQA::Scheduler;
# create Test DBus bus and service for fake WebSockets and Scheduler call
my $ipc = OpenQA::IPC->ipc('', 1);
my $ws = OpenQA::WebSockets->new;
my $sh = OpenQA::Scheduler->new;
my $test_case = OpenQA::Test::Case->new;
$test_case->init_data;
use t::ui::PhantomTest;
my $driver = t::ui::PhantomTest::call_phantom();
unless ($driver) {
plan skip_all => 'Install phantomjs and Selenium::Remote::Driver to run these tests';
exit(0);
}
my $elem;
my $baseurl;
my $decode_textarea;
my $dir = "t/data/openqa/share/tests/opensuse/needles";
# clean up needles dir
remove_tree($dir);
make_path($dir);
# default needle JSON content
my $default_json = '{"area" : [{"height" : 217,"type" : "match","width" : 384,"xpos" : 0,"ypos" : 0}],"tags" : ["ENV-VIDEOMODE-text","inst-timezone"]}';
# create a fake json
my $filen = "$dir/inst-timezone-text.json";
{
local $/; #Enable 'slurp' mode
open my $fh, ">", $filen;
print $fh $default_json;
close $fh;
}
sub open_needle_editor {
# init the preview
t::ui::PhantomTest::wait_for_ajax;
$driver->find_element('//a[@href="#step/installer_timezone/1"]')->click();
# init the diff
t::ui::PhantomTest::wait_for_ajax;
$driver->find_element('.step_actions .fa-thumb-tack', 'css')->click();
}
sub goto_editpage() {
is($driver->get_title(), "openQA", "on main page");
$baseurl = $driver->get_current_url();
$driver->find_element('Login', 'link_text')->click();
# we're back on the main page
is($driver->get_title(), "openQA", "back on main page");
is($driver->find_element('#user-action', 'css')->get_text(), 'Logged in as Demo', "logged in as demo");
$driver->get($baseurl . "tests/99946");
is($driver->get_title(), 'openQA: opensuse-13.1-DVD-i586-Build0091-textmode@32bit test results', 'tests/99946 followed');
open_needle_editor;
# no warnings about missing/bad needles present (yet)
my @warnings = $driver->find_elements('#editor_warnings', 'css');
is(scalar @warnings, 0, 'no warnings');
}
sub editpage_layout_check() {
t::ui::PhantomTest::wait_for_ajax;
# layout check
is($driver->find_element('#tags_select', 'css')->get_value(), 'inst-timezone-text', "inst-timezone tags selected");
is($driver->find_element('#image_select', 'css')->get_value(), 'screenshot', "Screenshot background selected");
is($driver->find_element('#area_select', 'css')->get_value(), 'inst-timezone-text', "inst-timezone areas selected");
is($driver->find_element('#take_matches', 'css')->is_selected(), 1, "Matches selected");
# check needle suggested name
my $today = strftime("%Y%m%d", gmtime(time));
is($driver->find_element('#needleeditor_name', 'css')->get_value(), "inst-timezone-text-$today", "has correct needle name");
# ENV-VIDEOMODE-text and inst-timezone tag are selected
is($driver->find_element('//input[@value="inst-timezone"]')->is_selected(), 1, "tag selected");
# workround property doesn't selected
is($driver->find_element('#property_workaround', 'css')->is_selected(), 0, "workaround property unselected");
$elem = $driver->find_element('#needleeditor_textarea', 'css');
$decode_textarea = decode_json($elem->get_value());
# the value already defined in $default_json
is($decode_textarea->{area}[0]->{xpos}, 0, "xpos correct");
is($decode_textarea->{area}[0]->{ypos}, 0, "ypos correct");
is($decode_textarea->{area}[0]->{width}, 384, "width correct");
is($decode_textarea->{area}[0]->{height}, 217, "height correct");
}
sub add_needle_tag(;$) {
my $tagname = shift || 'test-newtag';
$elem = $driver->find_element('#newtag', 'css');
$elem->send_keys($tagname);
$driver->find_element('#tag_add_button', 'css')->click();
t::ui::PhantomTest::wait_for_ajax;
is($driver->find_element("//input[\@value=\"$tagname\"]")->is_selected(), 1, "new tag found and was checked");
}
sub add_workaround_property() {
$driver->find_element('#property_workaround', 'css')->click();
t::ui::PhantomTest::wait_for_ajax;
is($driver->find_element('#property_workaround', 'css')->is_selected(), 1, "workaround property selected");
}
sub change_needle_value($$) {
my ($xoffset, $yoffset) = @_;
my $pre_offset = 10; # we need this value as first position the cursor moved on
my $decode_new_textarea;
$elem = $driver->find_element('#needleeditor_textarea', 'css');
$decode_textarea = decode_json($elem->get_value());
$elem = $driver->find_element('#needleeditor_canvas', 'css');
$driver->mouse_move_to_location(element => $elem, xoffset => $decode_textarea->{area}[0]->{xpos} + $pre_offset, yoffset => $decode_textarea->{area}[0]->{ypos} + $pre_offset);
$driver->button_down();
$driver->mouse_move_to_location(element => $elem, xoffset => $decode_textarea->{area}[0]->{xpos} + $xoffset + $pre_offset, yoffset => $decode_textarea->{area}[0]->{ypos} + $yoffset + $pre_offset);
$driver->button_up();
t::ui::PhantomTest::wait_for_ajax;
$elem = $driver->find_element('#needleeditor_textarea', 'css');
# check the value of textarea again
$decode_new_textarea = decode_json($elem->get_value());
is($decode_new_textarea->{area}[0]->{xpos}, $xoffset, "new xpos correct");
is($decode_new_textarea->{area}[0]->{ypos}, $yoffset, "new ypos correct");
# test match type
$decode_new_textarea = decode_json($elem->get_value());
is($decode_new_textarea->{area}[0]->{type}, "match", "type is match");
$driver->double_click; # the match type change to exclude
$decode_new_textarea = decode_json($elem->get_value());
is($decode_new_textarea->{area}[0]->{type}, "exclude", "type is exclude");
$driver->double_click; # the match type change to ocr
$decode_new_textarea = decode_json($elem->get_value());
is($decode_new_textarea->{area}[0]->{type}, "ocr", "type is ocr");
$driver->double_click; # the match type change back to match
unlike($driver->find_element('#change-match', 'css')->get_attribute('class'), qr/disabled/, "match level now enabled");
# test match level
$driver->find_element('#change-match', 'css')->click();
t::ui::PhantomTest::wait_for_ajax;
my $dialog = $driver->find_element('#change-match-form', 'css');
is($driver->find_element('#set_match', 'css')->is_displayed(), 1, "found set button");
is($driver->find_element('//input[@id="match"]')->get_value(), "96", "default match level is 96");
$driver->find_element('//input[@id="match"]')->clear();
$driver->find_element('//input[@id="match"]')->send_keys("99");
is($driver->find_element('//input[@id="match"]')->get_value(), "99", "set match level to 99");
$driver->find_element('#set_match', 'css')->click();
is($driver->find_element('#change-match-form', 'css')->is_hidden(), 1, "match level form closed");
$decode_new_textarea = decode_json($elem->get_value());
is($decode_new_textarea->{area}[0]->{match}, 99, "match level is 99 now");
}
sub overwrite_needle($) {
my ($needlename) = @_;
# remove animation from modal to speed up test
$driver->execute_script('$(\'#modal-overwrite\').removeClass(\'fade\');');
$driver->find_element('#needleeditor_name', 'css')->clear();
is($driver->find_element('#needleeditor_name', 'css')->get_value(), "", "needle name input clean up");
$driver->find_element('#needleeditor_name', 'css')->send_keys($needlename);
is($driver->find_element('#needleeditor_name', 'css')->get_value(), "$needlename", "new needle name inputed");
$driver->find_element('#save', 'css')->click();
t::ui::PhantomTest::wait_for_ajax;
my $diag;
$diag = $driver->find_element('#modal-overwrite', 'css');
is($driver->find_child_element($diag, '.modal-title', 'css')->is_displayed(), 1, "We can see the overwrite dialog");
is($driver->find_child_element($diag, '.modal-title', 'css')->get_text(), "Sure to overwrite test-newneedle?", "Needle part of the title");
$driver->find_element('#modal-overwrite-confirm', 'css')->click();
t::ui::PhantomTest::wait_for_ajax;
is($driver->find_element('#flash-messages span', 'css')->get_text(), "Needle test-newneedle created/updated. (restart job)", "highlight appears correct");
ok(-f "$dir/$needlename.json", "$needlename.json overwritten");
$driver->find_element('#flash-messages span a', 'css')->click();
# restart is an ajax call, for some reason the check/sleep interval must be at least 1 sec for this call
t::ui::PhantomTest::wait_for_ajax(1);
is($driver->get_title(), 'openQA: opensuse-13.1-DVD-i586-Build0091-textmode@32bit test results', "no longer on needle editor");
}
# start testing
goto_editpage();
editpage_layout_check();
# creating new needle
add_needle_tag();
my $needlename = 'test-newneedle';
# check needle name input
$driver->find_element('#needleeditor_name', 'css')->clear();
is($driver->find_element('#needleeditor_name', 'css')->get_value(), "", "needle name input clean up");
$driver->find_element('#needleeditor_name', 'css')->send_keys($needlename);
is($driver->find_element('#needleeditor_name', 'css')->get_value(), "$needlename", "new needle name inputed");
# create new needle by clicked save button
$driver->find_element('#save', 'css')->click();
t::ui::PhantomTest::wait_for_ajax;
# check state highlight appears with valid content
is($driver->find_element('#flash-messages span', 'css')->get_text(), "Needle test-newneedle created/updated. (restart job)", "highlight appears correct");
# check files are exists
ok(-f "$dir/$needlename.json", "$needlename.json created");
ok(-f "$dir/$needlename.png", "$needlename.png created");
# test overwrite needle
add_needle_tag('test-overwritetag');
add_workaround_property();
like($driver->find_element('#change-match', 'css')->get_attribute('class'), qr/disabled/, "match level disabled");
# change area
my $xoffset = my $yoffset = 200;
change_needle_value($xoffset, $yoffset); # xoffset and yoffset 200 for new area
overwrite_needle($needlename);
# parse new needle json
my $new_needle_path = "$dir/$needlename.json";
my $overwrite_json;
{
local $/; #Enable 'slurp' mode
open my $fh, "<", $new_needle_path;
$overwrite_json = <$fh>;
close $fh;
}
my $decode_json = decode_json($overwrite_json);
my $new_tags = $decode_json->{'tags'};
# check new needle json is correct
my $match = 0;
for my $tag (@$new_tags) {
$match = 1 if ($tag eq 'test-overwritetag');
}
is($match, 1, "found new tag in new needle");
is($decode_json->{'area'}[0]->{xpos}, $decode_textarea->{'area'}[0]->{xpos} + $xoffset, "new xpos stored to new needle");
is($decode_json->{'area'}[0]->{ypos}, $decode_textarea->{'area'}[0]->{ypos} + $yoffset, "new ypos stored to new needle");
subtest 'Deletion of needle is handled gracefully' => sub {
# re-open the needle editor after deleting needle
unlink $filen;
$driver->get($baseurl . "tests/99946");
is($driver->get_title(), 'openQA: opensuse-13.1-DVD-i586-Build0091-textmode@32bit test results', 'tests/99946 followed');
open_needle_editor;
is($driver->get_title(), 'openQA: Needle Editor', 'needle editor still shows up');
is($driver->find_element('#editor_warnings span', 'css')->get_text(), 'Could not find needle: inst-timezone-text for opensuse 13.1', 'warning about deleted needle is displayed');
};
t::ui::PhantomTest::kill_phantom();
subtest '(created) needles can be accessed over API' => sub {
my $t = Test::Mojo->new('OpenQA::WebAPI');
$t->get_ok('/needles/opensuse/test-newneedle.png')->status_is(200)->content_type_is('image/png');
my @warnings = warnings { $t->get_ok('/needles/opensuse/doesntexist.png')->status_is(404) };
map { like($_, qr/No such file or directory/, 'expected warning') } @warnings;
$t->get_ok('/needles/opensuse/test-newneedle.png?jsonfile=t/data/openqa/share/tests/opensuse/needles/test-newneedle.json')->status_is(200)->content_type_is('image/png');
@warnings = warnings { $t->get_ok('/needles/opensuse/test-newneedle.png?jsonfile=/try/to/break_out.json')->status_is(403) };
map { like($_, qr/is not in a subdir of/, 'expected warning') } @warnings;
};
done_testing();