use a debug function with time stamps
[mkws-moved-to-github.git] / test / spec / mkws-pazpar2.js
1 /* Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
2  *
3  * perform papzpar2 / pz2.js search & retrieve request in the browser
4  *
5  */
6
7 // get references from mkws.js, lazy evaluation
8 var debug = function (text) {
9         // use a debug function with time stamps
10         mkws.teams["AUTO"].log("Jasmine: " + text);
11
12         //mkws.log("Jasmine: " + text)
13     }
14
15     // Define empty jasmine_config for simple applications that don't define it.
16 if (jasmine_config == null || typeof jasmine_config != 'object') {
17     var jasmine_config = {};
18 }
19
20 var jasmine_status = {
21     source_click: 0
22 };
23
24 /* check config for jasmine test
25  *
26  * you can override the default values in the config
27  * object: jasmine_config = {};
28  *
29  */
30 function init_jasmine_config() {
31
32     var jasmine_config_default = {
33         search_query: "freebsd",
34         max_time: 17,
35         // in seconds
36         expected_hits: 80,
37         // at least expected hit counter
38         second: 1000,
39         // miliseconds to seconds
40         show_record_url: true,
41         // check for valid URL in records
42         check_motd: true,
43
44         // check sort by and per page menu
45         check_sortby: false,
46
47         dummy: false
48     };
49
50     // use default values for undefined values
51     for (var key in jasmine_config_default) {
52         if (!jasmine_config.hasOwnProperty(key)) {
53             jasmine_config[key] = jasmine_config_default[key];
54         }
55         debug("jasmine config: " + key + " => " + jasmine_config[key]);
56     }
57
58     mkws.jasmine_done = false;
59 }
60
61 var get_hit_counter = function () {
62         // not yet here
63         if (mkws.$(".mkwsPager").length == 0) return -1;
64
65         var found = mkws.$(".mkwsPager").text();
66         var re = /\([A-Za-z]+:\s+([0-9]+)\)/;
67         re.exec(found);
68         var hits = -1;
69
70         if (RegExp.$1) {
71             hits = parseInt(RegExp.$1);
72             if (hits <= 0) {
73                 debug("Oooops in get_hit_counter: " + RegExp.$1 + " '" + found + "'");
74             }
75         }
76
77         //debug("Hits: " + hits);
78         return hits;
79     }
80
81 describe("Init jasmine config", function () {
82     it("jasmine was successfully initialized", function () {
83         init_jasmine_config();
84
85         expect(jasmine_config.search_query).toMatch(/\w/);
86         expect(jasmine_config.second).toBeGreaterThan(100);
87         expect(jasmine_config.max_time).toBeGreaterThan(1);
88         expect(jasmine_config.expected_hits).toBeGreaterThan(1);
89     });
90 });
91
92 //disabled
93 xdescribe("Check MOTD before search", function () {
94     // Check that the MOTD has been moved into its container, and
95     // is visible before the search.
96     // the mkwsMOTD div was originally inside a testMOTD div, which should
97     // now be empty
98     // Note that the testMOTD is a regular div, and uses #testMOTD,
99     // since the automagic class-making does not apply to it.
100     it("MOTD is hidden", function () {
101         expect(mkws.$(".mkwsMOTD").length).toBe(1);
102         expect(mkws.$("#testMOTD").length).toBe(1);
103         expect(mkws.$("#testMOTD").text()).toMatch("^ *$");
104     });
105
106     it("mkwsMOTDContainer has received the text", function () {
107         expect(mkws.$(".mkwsMOTDContainer").length).toBe(1);
108         expect(mkws.$(".mkwsMOTDContainer").text()).toMatch(/MOTD/);
109     });
110 });
111
112 describe("Check pazpar2 search", function () {
113     it("pazpar2 was successfully initialized", function () {
114         expect(mkws.config.error).toBe(undefined);
115     });
116
117     it("validate HTML id's", function () {
118         expect(mkws.$("input.mkwsQuery").length).toBe(1);
119         expect(mkws.$("input.mkwsButton").length).toBe(1);
120
121         expect(mkws.$(".mkwsNext").length).not.toBe(1);
122         expect(mkws.$(".mkwsPrev").length).not.toBe(1);
123     });
124
125     it("run search query", function () {
126         var search_query = jasmine_config.search_query; // short hit counter with some paging
127         mkws.$("input.mkwsQuery").val(search_query);
128         debug("set search query: " + search_query)
129         expect(mkws.$("input.mkwsQuery").val()).toMatch("^" + search_query + "$");
130
131         if (mkws.config.use_service_proxy) {
132             // wait for service proxy auth
133             waitsFor(function () {
134                 return mkws.authenticated;
135             }, "SP auth done", 10 * jasmine_config.second);
136         } else {
137             debug("running raw pp2, don't wait for mkws auth");
138         }
139
140         runs(function () {
141             debug("Click on submit button");
142             mkws.$("input.mkwsButton").trigger("click");
143         })
144     });
145 });
146
147 describe("Check MOTD after search", function () {
148     it("MOTD is hidden", function () {
149         if (!jasmine_config.check_motd) {
150             return;
151         }
152
153         expect(mkws.$(".mkwsMOTD").length).toBe(1);
154         expect(mkws.$(".mkwsMOTD").is(":hidden")).toBe(true);
155         debug("motd t=" + mkws.$(".mkwsMOTD").text());
156         debug("motd v=" + mkws.$(".mkwsMOTD").is(":visible"));
157     });
158 });
159
160
161 /*
162  * This part runs in background. It should be rewritten with
163  * async jasmine functions
164  *
165  */
166 describe("Check pazpar2 navigation", function () {
167     // Asynchronous part
168     it("check running search next/prev", function () {
169         expect(mkws.$(".mkwsPager").length).toBe(1);
170
171         function my_click(id, time) {
172             setTimeout(function () {
173                 debug("trigger click on id: " + id);
174                 mkws.$(id).trigger("click");
175             }, time * jasmine_config.second);
176         }
177
178         waitsFor(function () {
179             return mkws.$("div.mkwsPager div:nth-child(2) a").length >= 2 ? true : false;
180         }, "Expect next link 2", 10 * jasmine_config.second);
181
182         runs(function () {
183             // click next/prev after N seconds
184             my_click(".mkwsNext", 0);
185         });
186
187         waitsFor(function () {
188             return mkws.$("div.mkwsPager div:nth-child(2) a").length >= 3 ? true : false;
189         }, "Expect next link 3", 5 * jasmine_config.second);
190
191         runs(function () {
192             // click next/prev after N seconds
193             my_click(".mkwsNext", 0);
194             my_click(".mkwsPrev", 0.2);
195         });
196     });
197 });
198
199 describe("Check pazpar2 hit counter", function () {
200     it("check running search hit counter", function () {
201         var max_time = jasmine_config.max_time; // in seconds
202         var expected_hits = jasmine_config.expected_hits; // at least expected hit counter
203         var hits = 0;
204
205         waitsFor(function () {
206             hits = get_hit_counter();
207             return hits > expected_hits;
208         }, "Expect " + expected_hits + " hits", max_time * jasmine_config.second);
209
210         runs(function () {
211             debug("mkws pager found records: '" + hits + "'");
212             expect(mkws.$(".mkwsPager").length).toBe(1);
213             expect(hits).toBeGreaterThan(expected_hits);
214         });
215     });
216 });
217
218 describe("Check Termlist", function () {
219     it("found Termlist", function () {
220         var termlist = mkws.$("div.mkwsTermlists");
221         debug("Termlist success: " + termlist.length);
222         expect(termlist.length).toBe(1);
223
224         waitsFor(function () {
225             return mkws.$("div.mkwsFacet[data-mkws-facet='xtargets']").length == 1 ? true : false;
226         }, "check for facet sources", 4 * jasmine_config.second);
227
228         // everything displayed?
229         runs(function () {
230             var sources = mkws.$("div.mkwsFacet[data-mkws-facet='xtargets']");
231             debug("Termlist sources success: " + sources.length);
232             expect(sources.length).toBe(1);
233
234             var subjects = mkws.$("div.mkwsFacet[data-mkws-facet='subject']");
235             expect(subjects.length).toBe(1);
236
237             var authors = mkws.$("div.mkwsFacet[data-mkws-facet='author']");
238             expect(authors.length).toBe(1);
239         });
240
241         waitsFor(function () {
242             return mkws.$("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm").length >= 2 ? true : false;
243         }, "At least one author link displayed", 4 * jasmine_config.second);
244
245         runs(function () {
246             expect(mkws.$("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm").length).toBeGreaterThan(1);
247         });
248     });
249 });
250
251
252
253 describe("Check Author Facets", function () {
254     it("limit search to first author", function () {
255         if (mkws.config.disable_facet_authors_search) {
256             debug("Facets: ignore limit search for authors");
257             return;
258         }
259
260         var hits_all_targets = get_hit_counter();
261         var author_number = 2; // 2=first author
262         // do not click on author with numbers, e.g.: "Bower, James M. Beeman, David, 1938-"
263         // do not click on author names without a comma, e.g.: "Joe Barbara"
264         // because searching on such authors won't find anything.
265         runs(function () {
266             var terms = mkws.$("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm a");
267             for (var i = 0; i < terms.length; i++) {
268                 var term = mkws.$(terms[i]).text();
269                 if (term.match(/[0-9].+[0-9]/i) || !term.match(/,/)) {
270                     debug("ignore author facet: " + term);
271                     author_number++;
272                 } else {
273                     break;
274                 }
275             }
276             if (mkws.$("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm:nth-child(" + author_number + ") a").text().length == 0) {
277                 debug("No good authors found. Not clicking on the bad ones");
278                 return;
279             }
280
281             debug("Clicking on author (" + author_number + ") " + mkws.$("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm:nth-child(" + author_number + ") a").text());
282             mkws.$("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm:nth-child(" + author_number + ") a").trigger("click");
283         });
284
285         waitsFor(function () {
286             var hits_single_target = get_hit_counter();
287             // debug("hits_single_target='" + hits_single_target + "' cf. hits_all_targets='" + hits_all_targets + "'");
288             return hits_single_target > 0 && hits_single_target < hits_all_targets ? true : false;
289         }, "Limited author search for less than " + hits_all_targets + " hits", 4.5 * jasmine_config.second);
290
291         runs(function () {
292             var hits_single_target = get_hit_counter();
293             debug("get less hits for authors: " + hits_all_targets + " > " + hits_single_target);
294         });
295     });
296 });
297
298 describe("Check active clients author", function () {
299     it("check for active clients after limited author search", function () {
300         waitsFor(function () {
301             var clients = mkws.$("div.mkwsStat span.mkwsClientCount");
302             // debug("clients: " + clients.text());
303             return clients.length == 1 && clients.text().match("/[1-9]+[0-9]*$");
304         }, "wait for Active clients: x/y", 5.5 * jasmine_config.second);
305
306         runs(function () {
307             var clients = mkws.$("div.mkwsStat span.mkwsClientCount");
308             debug("span.mkwsClientCount: " + clients.text());
309             expect(clients.text()).toMatch("/[1-9]+[0-9]*$");
310
311             // exact match of active clients (e.g. a SP misconfiguration)
312             if (jasmine_config.active_clients) {
313                 debug("check for " + jasmine_config.active_clients + " active connections");
314                 expect(clients.text()).toMatch(" [0-9]+/" + jasmine_config.active_clients + "$");
315             }
316         });
317     });
318 });
319
320 describe("Check Source Facets", function () {
321     it("limit search to first source", function () {
322         var hits_all_targets = get_hit_counter();
323         var source_number = 2; // 2=first source
324         // wait for a stat response
325         var waitcount = 0;
326         // do not click on wikipedia link - no author or subject facets possible
327         var link = "div.mkwsFacet[data-mkws-facet='xtargets'] div.mkwsTerm a";
328
329         // wait for a visible source link in facets
330         waitsFor(function () {
331             var terms = mkws.$(link);
332             return terms && terms.length > 0;
333         }, "wait for source facets after author search", 5 * jasmine_config.second);
334
335
336         runs(function () {
337             var terms = mkws.$(link);
338             for (var i = 0; i < terms.length; i++) {
339                 var term = mkws.$(terms[i]).text();
340                 debug("check for good source: " + term);
341
342                 if (term.match(/wikipedia/i)) {
343                     debug("ignore source facet: " + term);
344                     source_number++;
345                 } else {
346                     break;
347                 }
348             }
349             debug("Source counter: " + terms.length + ", select: " + (source_number - 1));
350
351             if (mkws.$("div.mkwsFacet[data-mkws-facet='xtargets'] div.mkwsTerm:nth-child(" + source_number + ") a").text().length == 0) {
352                 debug("No good source found. Not clicking on the bad ones");
353                 return;
354             }
355
356             debug("click on source link nth-child(): " + source_number);
357             mkws.$("div.mkwsFacet[data-mkws-facet='xtargets'] div.mkwsTerm:nth-child(" + source_number + ") a").trigger("click");
358
359             mkws.$(".mkwsPager").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
360                 waitcount++;
361                 debug("DOM wait for stat: " + waitcount);
362             });
363         });
364
365         waitsFor(function () {
366             if (mkws.$("div.mkwsNavi").length && mkws.$("div.mkwsNavi").text().match(/(Source|datenquelle|kilder): /i)) {
367                 return true;
368             } else {
369                 return false;
370             }
371         }, "Search for source in navi bar", 4 * jasmine_config.second);
372
373         // Note: it may happens that limited source search returns the same number of hits
374         // as before. Thats not really an error, but unfortunate
375         waitsFor(function () {
376             var hits_single_target = get_hit_counter();
377
378             return waitcount >= 2 && hits_single_target > 0 && hits_single_target <= hits_all_targets ? true : false;
379         }, "Limited source search for less than " + hits_all_targets + " hits", 5 * jasmine_config.second);
380
381         runs(function () {
382             var hits_single_target = get_hit_counter();
383             debug("get less hits for sources: " + hits_all_targets + " >= " + hits_single_target);
384             expect(hits_all_targets).not.toBeLessThan(hits_single_target);
385             jasmine_status.source_click = 1;
386
387             mkws.$(".mkwsPager").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
388         });
389     });
390 });
391
392
393 describe("Check record list", function () {
394     it("check for single active client", function () {
395         if (!jasmine_status.source_click) {
396             debug("skip clients check due missing source click");
397             return;
398         }
399
400         waitsFor(function () {
401             var clients = mkws.$("div.mkwsStat span.mkwsClientCount");
402             //debug("clients: " + clients.text());
403             return clients.length == 1 && clients.text().match("/1$");
404         }, "wait for Active clients: x/1", 5 * jasmine_config.second);
405
406         runs(function () {
407             var clients = mkws.$("div.mkwsStat span.mkwsClientCount");
408             debug("span.mkwsClientCount: " + clients.text());
409             expect(clients.text()).toMatch("/1$");
410         });
411     });
412
413     it("got a record", function () {
414         var linkaddr = "div.mkwsRecords div.mkwsSummary:nth-child(1) a";
415
416         waitsFor(function () {
417             // remove + insert node: must be at least 2
418             return mkws.$(linkaddr).length > 0;
419         }, "wait until we see a new record", 2.5 * jasmine_config.second);
420
421         runs(function () {
422             expect(mkws.$(linkaddr).length).toBeGreaterThan(0);
423         });
424     });
425 });
426
427 describe("Show record", function () {
428     var record_number = 1; // the Nth record in hit list
429     it("show record author", function () {
430         var click = mkws.$("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") a").trigger("click");
431         debug("show record click is success: " + click.length);
432         expect(click.length).toBe(1);
433
434         // wait until the record pops up
435         waitsFor(function () {
436             var show = mkws.$("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") > div.mkwsDetails");
437             //debug("poprecord: " + (show ? show.length : -1) + " " + mkws.$("div.mkwsRecords div.mkwsSummary").text());
438             return show != null && show.length ? true : false;
439         }, "wait some miliseconds to show up a record", 2 * jasmine_config.second);
440
441         runs(function () {
442             debug("show record pop up");
443             expect(mkws.$("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") div")).not.toBe(null);
444         });
445     });
446
447     it("extract URL", function () {
448         if (jasmine_config.show_record_url == false) {
449             debug("ignore test for URL in record")
450             return;
451         }
452
453         var urls = mkws.$("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") div table tbody tr td a");
454         debug("number of extracted URL from record: " + urls.length);
455         // expect(urls.length).toBeGreaterThan(0); // LoC has records without links
456         for (var i = 0; i < urls.length; i++) {
457             var url = mkws.$(urls[i]);
458             debug("URL: " + url.attr('href') + " text: " + url.text());
459
460             expect(url.attr('href')).not.toBe(null);
461             expect(url.attr('href')).toMatch(/^https?:\/\/[a-z0-9\-]+\.[0-9a-z].*\//i);
462             expect(url.text()).not.toBe("");
463         }
464     });
465 });
466
467 describe("Check switch menu Records/Targets", function () {
468     it("check mkwsSwitch", function () {
469         expect(mkws.$("div.mkwsSwitch").length).toBe(1);
470
471         // expect 2 clickable links
472         expect(mkws.$("div.mkwsSwitch > a").length).toBe(2);
473     });
474
475     it("switch to target view", function () {
476         mkws.$("div.mkwsSwitch > a").eq(1).trigger("click");
477
478         // now the target table must be visible
479         expect(mkws.$("div.mkwsTargets").is(":visible")).toBe(true);
480         expect(mkws.$("div.mkwsRecords").is(":visible")).toBe(false);
481
482         // wait a half second, to show the target view
483         var time = (new Date).getTime();
484         waitsFor(function () {
485             return (new Date).getTime() - time > 700 ? true : false;
486         }, "wait some miliseconds", 1 * jasmine_config.second);
487
488         // look for table header
489         runs(function () {
490             expect(mkws.$("div.mkwsTargets").html()).toMatch(/Target ID/);
491         });
492     });
493
494     it("switch back to record view", function () {
495         mkws.$("div.mkwsSwitch > a").eq(0).trigger("click");
496
497         // now the target table must be visible
498         expect(mkws.$("div.mkwsTargets").is(":visible")).toBe(false);
499         expect(mkws.$("div.mkwsRecords").is(":visible")).toBe(true);
500     });
501 });
502
503 describe("Check status client counter", function () {
504     function get_time() {
505         var date = new Date();
506         return date.getTime();
507     }
508     var time = get_time();
509
510     it("check status clients", function () {
511         if (!jasmine_status.source_click) {
512             debug("skip clients check due missing source click");
513             return;
514         }
515
516         waitsFor(function () {
517             var clients = mkws.$("div.mkwsStat span.mkwsClientCount");
518             debug("clients: " + clients.text());
519             if (clients.length == 1 && clients.text().match("0/1$")) {
520                 return true;
521             } else {
522                 return false;
523             }
524         }, "wait for Active clients: 0/1", 4 * jasmine_config.second);
525
526         runs(function () {
527             var clients = mkws.$("div.mkwsStat span.mkwsClientCount");
528             debug("span.mkwsClientCount: " + clients.text());
529             expect(clients.text()).toMatch("0/1$");
530         });
531     });
532 });
533
534 /* remove the "source" and "author" facet link to get more records again */
535 describe("Check removable facets links", function () {
536     var $ = mkws.$;
537
538     it("remove links for source and author", function () {
539         var waitcount = 0;
540         if (!jasmine_config.check_sortby) {
541             debug("ignore check for removable facets");
542             return;
543         }
544
545
546         runs(function () {
547             var click = $("a.mkwsRemovable").eq(0).trigger("click");
548             debug("Removed first facets link: " + click.length);
549             expect(click.length).toBe(1);
550         });
551
552         runs(function () {
553             $(".mkwsPager").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
554                 waitcount++;
555                 debug("DOM change for removeable: " + waitcount);
556             });
557         });
558
559         waitsFor(function () {
560             return $("a.mkwsRemovable").length == 1 ? 1 : 0;
561         });
562
563         runs(function () {
564             var click = $("a.mkwsRemovable").eq(0).trigger("click");
565             debug("Removed second facets link: " + click.length);
566             expect(click.length).toBe(1);
567         });
568
569         waitsFor(function () {
570             // debug("wait for: " + waitcount);
571             return waitcount >= 2 ? true : false;
572         }, "Records DOM change, by per page", 2 * jasmine_config.second);
573
574
575         runs(function () {
576             debug("unbind removable");
577             $(".mkwsPager").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
578         });
579     });
580 });
581
582
583 describe("Check per page options", function () {
584     var $ = mkws.$;
585
586     it("show per page", function () {
587         if (!jasmine_config.check_sortby) {
588             debug("ignore check for per page select");
589             return;
590         }
591         var waitcount = 0;
592         var per_page_number = 20;
593
594
595         runs(function () {
596             var select = $("select.mkwsPerpage option[selected='selected']");
597             debug("per page default is: " + select.text() + " and unselect it");
598             select.removeAttr('selected');
599
600             select = $("select.mkwsPerpage option[value='" + per_page_number + "']").attr('selected', true);
601             debug("per page is set to: " + select.text());
602             select.trigger("change");
603
604             $("div.mkwsRecords").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
605                 waitcount++;
606                 debug("DOM wait for change, per page: " + waitcount);
607             });
608         });
609
610         waitsFor(function () {
611             //debug("wait for: " + waitcount);
612             return waitcount >= 30 ? true : false;
613         }, "Records DOM change, by per page", 3 * jasmine_config.second);
614
615         runs(function () {
616             $("div.mkwsRecords").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
617             debug("unbind per page");
618         });
619
620         runs(function () {
621             var records = $("div.mkwsRecords > div.mkwsSummary");
622             debug("Got now " + records.length + " records");
623             expect(records.length).toBe(per_page_number);
624         });
625     });
626 });
627
628 describe("Check SortBy options", function () {
629     var $ = mkws.$;
630
631     it("show per page", function () {
632         if (!jasmine_config.check_sortby) {
633             debug("ignore check for sort by");
634             return;
635         }
636
637         var waitcount = 0;
638         var sort_value = 'title:1';
639         var per_page_number = 20;
640         var title_list_old = title_list("xxx ");
641
642         function title_list(prefix) {
643             var list = [];
644             var terms = $("div.mkwsRecords > div.mkwsSummary > a");
645             for (var i = 0; i < terms.length; i++) {
646                 var term = $(terms[i]).text();
647                 list.push(term);
648                 // debug(prefix + "title: " + term);
649             }
650             return list;
651         }
652
653         runs(function () {
654             $("div.mkwsRecords").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
655                 waitcount++;
656                 //debug("DOM wait for change, sort by: " + waitcount);
657             });
658
659             var select = $("select.mkwsSort option[selected='selected']");
660             debug("Sort by default is: " + select.text() + " and unselect it");
661             select.removeAttr('selected');
662
663             select = $("select.mkwsSort option[value='" + sort_value + "']").attr('selected', true);
664             debug("sort by is set to: " + select.text());
665             select.trigger("change");
666         });
667
668         waitsFor(function () {
669             //debug("wait for2: " + waitcount);
670             return waitcount >= 6 ? true : false;
671         }, "Records DOM change, by sort page", 3 * jasmine_config.second);
672
673         runs(function () {
674             $("div.mkwsRecords").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
675             debug("unbind per page");
676         });
677
678         runs(function () {
679             var records = $("div.mkwsRecords > div.mkwsSummary a");
680             debug("Got now " + records.length + " records");
681             expect(records.length).toBe(per_page_number);
682         });
683
684         runs(function () {
685             var title_list_new = title_list("yyy ");
686             var diff_flag = 0;
687             for (var i = 0; i < title_list_old.length; i++) {
688                 debug(title_list_old[i] + " :: " + title_list_new[i]);
689
690                 if (title_list_old[i] != title_list_new[i]) {
691                     diff_flag++;
692                 }
693             }
694             debug("Title changes: " + diff_flag + " out of " + per_page_number);
695             expect(diff_flag).not.toBe(0);
696         });
697     });
698 });
699
700
701 /* done */
702 describe("All tests are done", function () {
703     it(">>> hooray <<<", function () {
704         mkws.jasmine_done = true;
705     });
706 });