enable to tune timeouts, MKWS-384
[mkws-moved-to-github.git] / test / spec / mkws-pazpar2.js
1 /* Copyright (c) 2013-2014 Index Data 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"].info("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         // tune parameter for batch testing
34         batch_tuning: true,
35
36         search_query: "freebsd",
37         max_time: 17,
38         // in seconds
39         expected_hits: 80,
40         // at least expected hit counter
41         second: 1000,
42         // miliseconds to seconds
43         show_record_url: true,
44         // check for valid URL in records
45         check_motd: true,
46
47         // check sort by and per page menu
48         check_sortby: false,
49
50         dummy: false
51     };
52
53     // use default values for undefined values
54     for (var key in jasmine_config_default) {
55         if (!jasmine_config.hasOwnProperty(key)) {
56             jasmine_config[key] = jasmine_config_default[key];
57         }
58         debug("jasmine config: " + key + " => " + jasmine_config[key]);
59     }
60
61     // jenkins batch tests
62     if (jasmine_config.batch_tuning) {
63         var sec = mkws.getParameterByName("second", document.location);
64         if (sec && parseInt(sec) >= 100) {
65             jasmine_config.second = parseInt(sec);
66             debug("longer timeouts for batch testing: " + jasmine_config.second);
67         }
68     }
69
70     mkws.jasmine_done = false;
71 };
72
73 function get_hit_counter() {
74     var $ = mkws.$;
75     // not yet here
76     if ($(".mkws-pager").length == 0) return -1;
77
78     var found = $(".mkws-pager").text();
79     var re = /\([A-Za-z]+:\s+([0-9]+)\)/;
80     re.exec(found);
81     var hits = -1;
82
83     if (RegExp.$1) {
84         hits = parseInt(RegExp.$1);
85         if (hits <= 0) {
86             debug("Oooops in get_hit_counter: " + RegExp.$1 + " '" + found + "'");
87         }
88     }
89
90     //debug("Hits: " + hits);
91     return hits;
92 };
93
94 /******************************************************************************/
95 describe("Init jasmine config", function () {
96     it("jasmine was successfully initialized", function () {
97         init_jasmine_config();
98
99         expect(jasmine_config.search_query).toMatch(/\w/);
100         expect(jasmine_config.second).toBeGreaterThan(100);
101         expect(jasmine_config.max_time).toBeGreaterThan(1);
102         expect(jasmine_config.expected_hits).toBeGreaterThan(1);
103     });
104 });
105
106 //disabled
107 xdescribe("Check MOTD before search", function () {
108     var $ = mkws.$;
109
110     // Check that the MOTD has been moved into its container, and
111     // is visible before the search.
112     // the mkws-motd div was originally inside a testMOTD div, which should
113     // now be empty
114     // Note that the testMOTD is a regular div, and uses #testMOTD,
115     // since the automagic class-making does not apply to it.
116     it("MOTD is hidden", function () {
117         expect($(".mkws-motd").length).toBe(1);
118         expect($("#testMOTD").length).toBe(1);
119         expect($("#testMOTD").text()).toMatch("^ *$");
120     });
121
122     it("mkws-motd-container has received the text", function () {
123         expect($(".mkws-motd-container").length).toBe(1);
124         expect($(".mkws-motd-container").text()).toMatch(/MOTD/);
125     });
126 });
127
128 describe("Check pazpar2 search", function () {
129     var $ = mkws.$;
130
131     it("pazpar2 was successfully initialized", function () {
132         expect(mkws.config.error).toBe(undefined);
133     });
134
135     it("validate HTML id's", function () {
136         expect($("input.mkws-query").length).toBe(1);
137         expect($("input.mkws-button").length).toBe(1);
138
139         expect($(".mkws-next").length).not.toBe(1);
140         expect($(".mkws-prev").length).not.toBe(1);
141     });
142
143     it("run search query", function () {
144         var search_query = jasmine_config.search_query; // short hit counter with some paging
145         $("input.mkws-query").val(search_query);
146         debug("set search query: " + search_query)
147         expect($("input.mkws-query").val()).toMatch("^" + search_query + "$");
148
149         if (mkws.config.use_service_proxy) {
150             // wait for service proxy auth
151             waitsFor(function () {
152                 return mkws.authenticated;
153             }, "SP auth done", 10 * jasmine_config.second);
154         } else {
155             debug("running raw pp2, don't wait for mkws auth");
156         }
157
158         runs(function () {
159             debug("Click on submit button");
160             $("input.mkws-button").trigger("click");
161         })
162     });
163 });
164
165 describe("Check MOTD after search", function () {
166     var $ = mkws.$;
167
168     it("MOTD is hidden", function () {
169         if (!jasmine_config.check_motd) {
170             return;
171         }
172
173         expect($(".mkws-motd").length).toBe(1);
174         expect($(".mkws-motd").is(":hidden")).toBe(true);
175         debug("motd t=" + $(".mkws-motd").text());
176         debug("motd v=" + $(".mkws-motd").is(":visible"));
177     });
178 });
179
180
181 /*
182  * This part runs in background. It should be rewritten with
183  * async jasmine functions
184  *
185  */
186 describe("Check pazpar2 navigation", function () {
187     var $ = mkws.$;
188
189     // Asynchronous part
190     it("check running search next/prev", function () {
191         expect($(".mkws-pager").length).toBe(1);
192
193         function my_click(id, time) {
194             setTimeout(function () {
195                 debug("trigger click on id: " + id);
196                 $(id).trigger("click");
197             }, time * jasmine_config.second);
198         }
199
200         waitsFor(function () {
201             return $("div.mkws-pager div:nth-child(2) a").length >= 2 ? true : false;
202         }, "Expect next link 2", 10 * jasmine_config.second);
203
204         runs(function () {
205             // click next/prev after N seconds
206             my_click(".mkws-next", 0);
207         });
208
209         waitsFor(function () {
210             return $("div.mkws-pager div:nth-child(2) a").length >= 3 ? true : false;
211         }, "Expect next link 3", 5 * jasmine_config.second);
212
213         runs(function () {
214             // click next/prev after N seconds
215             my_click(".mkws-next", 0);
216             my_click(".mkws-prev", 0.2);
217         });
218     });
219 });
220
221 describe("Check pazpar2 hit counter", function () {
222     var $ = mkws.$;
223
224     it("check running search hit counter", function () {
225         var max_time = jasmine_config.max_time; // in seconds
226         var expected_hits = jasmine_config.expected_hits; // at least expected hit counter
227         var hits = 0;
228
229         waitsFor(function () {
230             hits = get_hit_counter();
231             return hits > expected_hits;
232         }, "Expect " + expected_hits + " hits", max_time * jasmine_config.second);
233
234         runs(function () {
235             debug("mkws pager found records: '" + hits + "'");
236             expect($(".mkws-pager").length).toBe(1);
237             expect(hits).toBeGreaterThan(expected_hits);
238         });
239     });
240 });
241
242 describe("Check Facets", function () {
243     var $ = mkws.$;
244
245     it("found Facets", function () {
246         var facets = $("div.mkws-facets");
247         debug("Facet success: " + facets.length);
248         expect(facets.length).toBe(1);
249
250         waitsFor(function () {
251             return $("div.mkws-facet[data-mkws-facet='xtargets']").length == 1 ? true : false;
252         }, "check for facet sources", 4 * jasmine_config.second);
253
254         // everything displayed?
255         runs(function () {
256             var sources = $("div.mkws-facet[data-mkws-facet='xtargets']");
257             debug("Facet sources success: " + sources.length);
258             expect(sources.length).toBe(1);
259
260             var subjects = $("div.mkws-facet[data-mkws-facet='subject']");
261             expect(subjects.length).toBe(1);
262
263             var authors = $("div.mkws-facet[data-mkws-facet='author']");
264             expect(authors.length).toBe(1);
265         });
266
267         waitsFor(function () {
268             return $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term").length >= 2 ? true : false;
269         }, "At least two author link displayed", 4 * jasmine_config.second);
270
271         runs(function () {
272             expect($("div.mkws-facet[data-mkws-facet='author'] div.mkws-term").length).toBeGreaterThan(1);
273         });
274     });
275 });
276
277
278
279 describe("Check Author Facets", function () {
280     var $ = mkws.$;
281
282     it("limit search to first author", function () {
283         if (mkws.config.disable_facet_authors_search) {
284             debug("Facets: ignore limit search for authors");
285             return;
286         }
287
288         var hits_all_targets = get_hit_counter();
289         var author_number = 2; // 2=first author
290         // do not click on author with numbers, e.g.: "Bower, James M. Beeman, David, 1938-"
291         // do not click on author names without a comma, e.g.: "Joe Barbara"
292         // because searching on such authors won't find anything.
293         runs(function () {
294             var terms = $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term a");
295             for (var i = 0; i < terms.length; i++) {
296                 var term = $(terms[i]).text();
297                 if (term.match(/[0-9].+[0-9]/i) || !term.match(/,/)) {
298                     debug("ignore author facet: " + term);
299                     author_number++;
300                 } else {
301                     break;
302                 }
303             }
304             if ($("div.mkws-facet[data-mkws-facet='author'] div.mkws-term:nth-child(" + author_number + ") a").text().length == 0) {
305                 debug("No good authors found. Not clicking on the bad ones");
306                 return;
307             }
308
309             debug("Clicking on author (" + author_number + ") " + $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term:nth-child(" + author_number + ") a").text());
310             $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term:nth-child(" + author_number + ") a").trigger("click");
311         });
312
313         waitsFor(function () {
314             var hits_single_target = get_hit_counter();
315             // debug("hits_single_target='" + hits_single_target + "' cf. hits_all_targets='" + hits_all_targets + "'");
316             return hits_single_target > 0 && hits_single_target < hits_all_targets ? true : false;
317         }, "Limited author search for less than " + hits_all_targets + " hits", 4.5 * jasmine_config.second);
318
319         runs(function () {
320             var hits_single_target = get_hit_counter();
321             debug("get less hits for authors: " + hits_all_targets + " > " + hits_single_target);
322         });
323     });
324 });
325
326 describe("Check active clients author", function () {
327     var $ = mkws.$;
328
329     it("check for active clients after limited author search", function () {
330         waitsFor(function () {
331             var clients = $("div.mkws-stat span.mkws-client-count");
332             // debug("clients: " + clients.text());
333             return clients.length == 1 && clients.text().match("/[1-9]+[0-9]*$");
334         }, "wait for Active clients: x/y", 5.5 * jasmine_config.second);
335
336         runs(function () {
337             var clients = $("div.mkws-stat span.mkws-client-count");
338             debug("span.mkws-client-count: " + clients.text());
339             expect(clients.text()).toMatch("/[1-9]+[0-9]*$");
340
341             // exact match of active clients (e.g. a SP misconfiguration)
342             if (jasmine_config.active_clients) {
343                 debug("check for " + jasmine_config.active_clients + " active connections");
344                 expect(clients.text()).toMatch(" [0-9]+/" + jasmine_config.active_clients + "$");
345             }
346         });
347     });
348 });
349
350 describe("Check Source Facets", function () {
351     var $ = mkws.$;
352
353     it("limit search to first source", function () {
354         var hits_all_targets = get_hit_counter();
355         var source_number = 2; // 2=first source
356         // wait for a stat response
357         var waitcount = 0;
358         // do not click on wikipedia link - no author or subject facets possible
359         var link = "div.mkws-facet[data-mkws-facet='xtargets'] div.mkws-term a";
360
361         // wait for a visible source link in facets
362         waitsFor(function () {
363             var terms = $(link);
364             return terms && terms.length > 0;
365         }, "wait for source facets after author search", 5 * jasmine_config.second);
366
367
368         runs(function () {
369             var terms = $(link);
370             for (var i = 0; i < terms.length; i++) {
371                 var term = $(terms[i]).text();
372                 debug("check for good source: " + term);
373
374                 if (term.match(/wikipedia/i)) {
375                     debug("ignore source facet: " + term);
376                     source_number++;
377                 } else {
378                     break;
379                 }
380             }
381             debug("Source counter: " + terms.length + ", select: " + (source_number - 1));
382
383             if ($("div.mkws-facet[data-mkws-facet='xtargets'] div.mkws-term:nth-child(" + source_number + ") a").text().length == 0) {
384                 debug("No good source found. Not clicking on the bad ones");
385                 return;
386             }
387
388             debug("click on source link nth-child(): " + source_number);
389             $("div.mkws-facet[data-mkws-facet='xtargets'] div.mkws-term:nth-child(" + source_number + ") a").trigger("click");
390
391             $(".mkws-pager").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
392                 waitcount++;
393                 debug("DOM change mkws-pager, for stat: " + waitcount);
394             });
395         });
396
397         waitsFor(function () {
398             if ($("div.mkws-navi").length && $("div.mkws-navi").text().match(/(Source|datenquelle|kilder): /i)) {
399                 return true;
400             } else {
401                 return false;
402             }
403         }, "Search for source in navi bar", 4 * jasmine_config.second);
404
405         // Note: it may happens that limited source search returns the same number of hits
406         // as before. Thats not really an error, but unfortunate
407         waitsFor(function () {
408             var hits_single_target = get_hit_counter();
409
410             return waitcount >= 2 && hits_single_target > 0 && hits_single_target <= hits_all_targets ? true : false;
411         }, "Limited source search for less than " + hits_all_targets + " hits", 5 * jasmine_config.second);
412
413         runs(function () {
414             var hits_single_target = get_hit_counter();
415             debug("get less hits for sources: " + hits_all_targets + " >= " + hits_single_target);
416             expect(hits_all_targets).not.toBeLessThan(hits_single_target);
417             jasmine_status.source_click = 1;
418
419             $(".mkws-pager").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
420         });
421     });
422 });
423
424
425 describe("Check record list", function () {
426     var $ = mkws.$;
427
428     it("check for single active client", function () {
429         if (!jasmine_status.source_click) {
430             debug("skip clients check due missing source click");
431             return;
432         }
433
434         waitsFor(function () {
435             var clients = $("div.mkws-stat span.mkws-client-count");
436             //debug("clients: " + clients.text());
437             return clients.length == 1 && clients.text().match("/1$");
438         }, "wait for Active clients: x/1", 5 * jasmine_config.second);
439
440         runs(function () {
441             var clients = $("div.mkws-stat span.mkws-client-count");
442             debug("span.mkws-client-count: " + clients.text());
443             expect(clients.text()).toMatch("/1$");
444         });
445     });
446
447     it("got a record", function () {
448         var linkaddr = "div.mkws-records div.mkws-summary:nth-child(1) a";
449
450         waitsFor(function () {
451             // remove + insert node: must be at least 2
452             return $(linkaddr).length > 0;
453         }, "wait until we see a new record", 2.5 * jasmine_config.second);
454
455         runs(function () {
456             expect($(linkaddr).length).toBeGreaterThan(0);
457         });
458     });
459 });
460
461 describe("Show record", function () {
462     var $ = mkws.$;
463
464     var record_number = 1; // the Nth record in hit list
465     it("show record author", function () {
466         var click = $("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") a").trigger("click");
467         debug("show record click is success: " + click.length);
468         expect(click.length).toBe(1);
469
470         // wait until the record pops up
471         waitsFor(function () {
472             var show = $("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") > div.mkws-details");
473             //debug("poprecord: " + (show ? show.length : -1) + " " + $("div.mkws-records div.mkws-summary").text());
474             return show != null && show.length ? true : false;
475         }, "wait some miliseconds to show up a record", 2 * jasmine_config.second);
476
477         runs(function () {
478             debug("show record pop up");
479             expect($("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") div")).not.toBe(null);
480         });
481     });
482
483     it("extract URL", function () {
484         if (jasmine_config.show_record_url == false) {
485             debug("ignore test for URL in record")
486             return;
487         }
488
489         var urls = $("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") div table tbody tr td a");
490         debug("number of extracted URL from record: " + urls.length);
491         // expect(urls.length).toBeGreaterThan(0); // LoC has records without links
492         for (var i = 0; i < urls.length; i++) {
493             var url = $(urls[i]);
494             debug("URL: " + url.attr('href') + " text: " + url.text());
495
496             expect(url.attr('href')).not.toBe(null);
497             expect(url.attr('href')).toMatch(/^https?:\/\/[a-z0-9\-]+\.[0-9a-z].*\//i);
498             expect(url.text()).not.toBe("");
499         }
500     });
501 });
502
503 describe("Check switch menu Records/Targets", function () {
504     var $ = mkws.$;
505
506     it("check mkws-switch", function () {
507         expect($("div.mkws-switch").length).toBe(1);
508
509         // expect 2 clickable links
510         expect($("div.mkws-switch > a").length).toBe(2);
511     });
512
513     it("switch to target view", function () {
514         $("div.mkws-switch > a").eq(1).trigger("click");
515
516         // now the target table must be visible
517         expect($("div.mkws-targets").is(":visible")).toBe(true);
518         expect($("div.mkws-records").is(":visible")).toBe(false);
519
520         // wait a half second, to show the target view
521         var time = (new Date).getTime();
522         waitsFor(function () {
523             return (new Date).getTime() - time > 700 ? true : false;
524         }, "wait some miliseconds", 1 * jasmine_config.second);
525
526         // look for table header
527         runs(function () {
528             expect($("div.mkws-targets").html()).toMatch(/Target ID/);
529         });
530     });
531
532     it("switch back to record view", function () {
533         $("div.mkws-switch > a").eq(0).trigger("click");
534
535         // now the target table must be visible
536         expect($("div.mkws-targets").is(":visible")).toBe(false);
537         expect($("div.mkws-records").is(":visible")).toBe(true);
538     });
539 });
540
541 describe("Check translations", function () {
542     var $ = mkws.$;
543
544     // handle html entities, "Zur&uuml;ck" => "Zurück"
545     var M = function (string) {
546             var text = $("<span/>").html(mkws.M(string)).text()
547             debug("translate check for: " + text);
548             return text;
549         };
550     var lang = function () {
551             return mkws.config.lang
552         };
553
554     function check_translation(list, text) {
555         expect(list.length).toBe(text.length);
556
557         for (var i = 0; i < text.length; i++) {
558             expect($(list[i]).text()).toBe(M(text[i]));
559         }
560     }
561
562     it("check language", function () {
563         var lang = mkws.config.lang;
564         debug("lang: " + lang);
565         expect(lang).toMatch(/^(de|da|)$/);
566     });
567
568 /*
569   locale_lang: {
570     "de": {
571       "Authors": "Autoren",
572       "Subjects": "Schlagw&ouml;rter",
573       "Sources": "Daten und Quellen",
574       "source": "datenquelle",
575       "Facets": "Termlisten",
576       "Next": "Weiter",
577       "Prev": "Zur&uuml;ck",
578       "Search": "Suche",
579       "Sort by": "Sortieren nach",
580       "and show": "und zeige",
581       "per page": "pro Seite",
582       "Displaying": "Zeige",
583       "to": "von",
584       "of": "aus",
585       "found": "gefunden",
586       "Title": "Titel",
587       "Author": "Autor",
588       "author": "autor",
589       "Date": "Datum",
590       "Subject": "Schlagwort",
591       "subject": "schlagwort",
592       "Location": "Ort",
593       "Records": "Datens&auml;tze",
594       "Targets": "Datenbanken",
595       "relevance": "Relevanz",
596       "title": "Titel",
597       "newest": "Neueste",
598       "oldest": "&Auml;lteste",
599
600       "dummy": "dummy"
601     },
602 */
603
604     it("search button", function () {
605         var list = $(".mkws-pager-desc > span");
606         expect($("form > input[type=submit]").attr("value")).toBe(M("Search"));
607     });
608
609     it("switch", function () {
610         var list = $(".mkws-switch > a")
611         var text = ["Records", "Targets"];
612
613         check_translation(list, text);
614     });
615
616
617     it("ranking form", function () {
618         var list = $(".mkws-ranking > form > span");
619         var text = ["Sort by", "and show", "per page"];
620
621         check_translation(list, text);
622
623         // double check
624         if (lang == "de") {
625             expect("Sortieren nach").toBe(M("Sort by"));
626             expect("Sortieren nach").toBe($(list[0]).text());
627         } else if (lang == "da") {
628             expect("Sorter efter").toBe(M("Sort by"));
629             expect("Sorter efter").toBe($(list[0]).text());
630         }
631
632
633         expect($("select.mkws-sort > option[selected=selected]").text()).toBe(M("relevance"));
634     });
635
636     it("facets sidebar", function () {
637         var list = $(".mkws-facet-title");
638         var text = ["Sources", "Subjects", "Authors"];
639
640         check_translation(list, text);
641     });
642
643     it("facets navigation/filter", function () {
644         var list = $(".mkws-navi > span");
645         var text = ["source", "author"];
646
647         check_translation(list, text);
648     });
649
650     it("navigation", function () {
651         var list = $(".mkws-pager-desc > span");
652         var text = ["Displaying", "to", "of", "found"];
653
654         check_translation(list, text);
655
656         expect($(".mkws-next").text()).toBe(M("Next"));
657         expect($(".mkws-prev").text()).toBe(M("Prev"));
658     });
659
660     it("record details", function () {
661         var text = ["Title", "Date", "Author"]; // , "Subject", "Locations"];
662         var list = $("div.mkws-details table > tbody > tr > th");
663
664         // compare only the first 3 elements
665         list = list.splice(0, text.length)
666
667         check_translation(list, text);
668     });
669
670 /* not tested
671      *
672      * Status line:  -- Active clients : 0/1 -- Retrieved records : 4/4
673      *
674      */
675 });
676
677 describe("Check status client counter", function () {
678     var $ = mkws.$;
679
680     function get_time() {
681         var date = new Date();
682         return date.getTime();
683     }
684     var time = get_time();
685
686     it("check status clients", function () {
687         if (!jasmine_status.source_click) {
688             debug("skip clients check due missing source click");
689             return;
690         }
691
692         waitsFor(function () {
693             var clients = $("div.mkws-stat span.mkws-client-count");
694             debug("clients: " + clients.text());
695             if (clients.length == 1 && clients.text().match("0/1$")) {
696                 return true;
697             } else {
698                 return false;
699             }
700         }, "wait for Active clients: 0/1", 4 * jasmine_config.second);
701
702         runs(function () {
703             var clients = $("div.mkws-stat span.mkws-client-count");
704             debug("span.mkws-client-count: " + clients.text());
705             expect(clients.text()).toMatch("0/1$");
706         });
707     });
708 });
709
710 /* remove the "source" and "author" facet link to get more records again */
711 describe("Check removable facets links", function () {
712     var $ = mkws.$;
713
714     it("remove links for source and author", function () {
715         var waitcount = 0;
716         if (!jasmine_config.check_sortby) {
717             debug("ignore check for removable facets");
718             return;
719         }
720
721
722         runs(function () {
723             var click = $("a.mkws-removable").eq(0).trigger("click");
724             debug("Removed first facets link: " + click.length);
725             expect(click.length).toBe(1);
726         });
727
728         runs(function () {
729             $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
730                 waitcount++;
731                 if (waitcount <= 5 || (waitcount % 5 == 0)) {
732                     debug("DOM change mkws-records for removeable: " + waitcount);
733                 }
734             });
735         });
736
737         waitsFor(function () {
738             return waitcount >= 2 && $("a.mkws-removable").length == 1 ? 1 : 0;
739         }, "Records DOM change mkws-records, removable", 2 * jasmine_config.second);
740
741         runs(function () {
742             debug("unbind removable");
743             $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
744             waitcount = 0;
745
746             $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
747                 waitcount++;
748                 if (waitcount <= 5 || (waitcount % 5 == 0)) {
749                     debug("DOM change mkws-records for removeable2: " + waitcount);
750                 }
751             });
752
753             var click = $("a.mkws-removable").eq(0).trigger("click");
754             debug("Removed second facets link: " + click.length);
755             expect(click.length).toBe(1);
756         });
757
758         waitsFor(function () {
759             return waitcount >= 2 && $("a.mkws-removable").length == 0 ? true : false;
760         }, "DOM change mkws-records, removable2", 2 * jasmine_config.second);
761
762         runs(function () {
763             debug("unbind removable2");
764             $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
765         });
766     });
767 });
768
769
770 describe("Check per page options", function () {
771     var $ = mkws.$;
772
773     it("show per page", function () {
774         if (!jasmine_config.check_sortby) {
775             debug("ignore check for per page select");
776             return;
777         }
778         var waitcount = 0;
779         var per_page_number = 20;
780
781
782         runs(function () {
783             var select = $("select.mkws-perpage option[selected='selected']");
784             debug("per page default is: " + select.text() + " and unselect it");
785             select.removeAttr('selected');
786
787             select = $("select.mkws-perpage option[value='" + per_page_number + "']").attr('selected', true);
788             debug("per page is set to: " + select.text());
789             select.trigger("change");
790
791             $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
792                 waitcount++;
793                 if (waitcount <= 5 || (waitcount % 10 == 0)) {
794                     debug("DOM change mkws-records, per page: " + waitcount);
795                 }
796             });
797         });
798
799         waitsFor(function () {
800             // debug("per page waitcounter: " + waitcount)
801             return waitcount >= (per_page_number + 10) ? true : false;
802         }, "DOM change mkws-records, by per page", 3 * jasmine_config.second);
803
804         runs(function () {
805             debug("unbind per page");
806             $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
807
808             var records = $("div.mkws-records > div.mkws-summary");
809             debug("Per page got now " + records.length + " records");
810             expect(records.length).toBe(per_page_number);
811         });
812     });
813 });
814
815 describe("Check SortBy options", function () {
816     var $ = mkws.$;
817
818     it("sort by title", function () {
819         if (!jasmine_config.check_sortby) {
820             debug("ignore check for sort by");
821             return;
822         }
823
824         var waitcount = 0;
825         var sort_value = 'title:1';
826         var per_page_number = 20;
827
828         // keep current title list
829         var title_list_old = title_list("xxx ");
830
831         function title_list(prefix) {
832             var list = [];
833             var terms = $("div.mkws-records > div.mkws-summary > div.mkws-field-data span.mkws-field-title");
834             for (var i = 0; i < terms.length; i++) {
835                 var term = $(terms[i]).text().trim();
836                 list.push(term);
837                 // debug(prefix + "title: " + term);
838             }
839             return list;
840         }
841
842         runs(function () {
843             $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
844                 waitcount++;
845                 if (waitcount <= 5 || (waitcount % 10 == 0)) {
846                     debug("DOM change mkws-records, sort by: " + waitcount);
847                 }
848             });
849
850             var select = $("select.mkws-sort option[selected='selected']");
851             debug("Sort by default is: " + select.text() + " and unselect it");
852             select.removeAttr('selected');
853
854             select = $("select.mkws-sort option[value='" + sort_value + "']").attr('selected', true);
855             debug("sort by is set to: " + select.text());
856             select.trigger("change");
857         });
858
859         waitsFor(function () {
860             //debug("wait for2: " + waitcount);
861             return waitcount >= (per_page_number + 10) ? true : false;
862         }, "DOM change mkws-records, by sort page", 3 * jasmine_config.second);
863
864         runs(function () {
865             $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
866             debug("unbind by sort");
867
868             var records = $("div.mkws-records > div.mkws-summary");
869             debug("Sort by got now " + records.length + " records");
870             expect(records.length).toBe(per_page_number);
871         });
872
873         runs(function () {
874             var title_list_new = title_list("yyy ");
875             var diff_flag = 0;
876             for (var i = 0; i < title_list_old.length; i++) {
877                 debug((i + 1) + ". " + title_list_old[i] + " :: " + title_list_new[i]);
878
879                 if (title_list_old[i] != title_list_new[i]) {
880                     diff_flag++;
881                 }
882             }
883             debug("Title changes: " + diff_flag + " out of " + per_page_number);
884             expect(diff_flag).not.toBe(0);
885         });
886     });
887 });
888
889
890 xdescribe("Check async widget discovery", function () {
891     var $ = mkws.$;
892     it("initialises a new widget", function () {
893         $("div.mkws-search").after('<div id="asyncSearch"><div class="mkws-search mkws-team-async"></div></div>');
894         mkws.init("Another search box", "#asyncSearch");
895         waitsFor(function () {
896             return $("#asyncSearch input").length >= 1 ? true : false;
897         }, "Call init() to build an .mkws-search", 750);
898         runs(function () {
899             var numInput = $("div.mkws-search input").length;
900             debug("Input elements present: " + numInput);
901             expect(numInput).toBe(4);
902             var numRec = $("div.mkws-records > div.mkws-summary").length;
903             debug("Records should still be present. There are: " + numRec);
904             expect(numRec).toBeGreaterThan(0);
905         });
906     });
907 });
908
909 /* done */
910 describe("All tests are done", function () {
911     it(">>> hooray <<<", function () {
912         mkws.jasmine_done = true;
913         debug(">>> hooray <<<");
914     });
915 });