source: ether_iasi/trunk/web/resources/js/OpenLayers-2.12/tests/auto-tests.html @ 738

Last change on this file since 738 was 738, checked in by vmipsl, 11 years ago

OpenLayers?

File size: 89.5 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html><head>
3<meta http-equiv="refresh" content="1200" />
4<title> Run the testsuite</title>
5<noscript>Javascript is disabled in your browser. This page cannot be displayed correctly without Javascript. Sorry. <br/> If you want to view this page, please change your browser settings so that Javascript is enabled.</noscript>
6<!--
7Test.AnotherWay version 0.5
8
9Copyright (c) 2005 Artem Khodush, http://straytree.org
10
11Permission is hereby granted, free of charge, to any person obtaining
12a copy of this software and associated documentation files (the
13"Software"), to deal in the Software without restriction, including
14without limitation the rights to use, copy, modify, merge, publish,
15distribute, sublicense, and/or sell copies of the Software, and to
16permit persons to whom the Software is furnished to do so, subject to
17the following conditions:
18
19The above copyright notice and this permission notice shall be
20included in all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29-->
30<style type="text/css">
31* { padding: 0; margin: 0; }
32html { height: 99%; }
33body { height: 98%; font: normal normal 10pt sans-serif }
34#col1 {  float: left; width: 27em; margin: 0 0 0 1em; overflow: visible; }
35#col2 {  position: relative; height: 98%; margin: 0 0.5em 0 28em; }
36#col1_header { margin-top: 0.5em; }
37#scroller { height: 400px; overflow: auto;}
38#testtable { margin: 0 0 2em 0; width: 97%; }
39#run_buttons { margin-bottom: 4em; }
40
41#right_header { padding-top: 0.8em; }
42#results_count { float: left; }
43.active_tab                     { float: right; padding: 0 1em 0.2em 1em; background: #0af; border: 1px solid #048; border-bottom: none; cursor: pointer; cursor: hand;
44                                         position: relative; top: -0.2em; }
45.inactive_tab                   { float: right; padding: 0 1em 0 1em; background: #9bb; color: #444; border: 1px solid #9bb; border-bottom: none; cursor: pointer; cursor: hand; }
46.inactive_mouseover_tab         { float: right; padding: 0 1em 0 1em; background: #9bb; color: #062; border: 1px solid #062; border-bottom: none; cursor: pointer; cursor: hand; }
47
48#right_frame { overflow: auto; position: relative; top: -0.2em; clear: right; height: 95%; border: 1px solid #048; }
49
50#debug { display: none; }
51#debug p { margin: 2px 0 0 5em; text-indent: -4.8em; }
52
53#error { display: none; color: #c22; }
54
55#results p { margin: 0 0 2px 0; }
56/* cursor indicating that detailed results may be expanded/contracted */
57#results p.badtest { cursor: text; }
58#results p.ok, #results p.fail { cursor: pointer; cursor: hand; }
59
60/* colored squares in the results window at the left of test page names */
61#results p.ok .bullet { background: #6d6; }
62#results p.fail .bullet { background:  #d46; }
63#results p.badtest .bullet { background: #ea3; }
64#results p.loading .bullet { background: #48f; }
65#results p.running .bullet { background: #26e; }
66#results p.waiting .bullet { background: #04d; }
67/* highlight in the results line */
68#results p .warning { background: #ffc; }
69
70/* layout of the detailed results */
71.result_detail { padding-left: 3em; }
72.result_exception_detail { padding-left: 4em; }
73.result_exception_stack_detail { padding-left: 5em;  }
74.result_micro_detail { padding-left: 6em; }
75/* colouring in the detailed results */
76.result_detail .fail, .result_exception_detail .fail,  .result_micro_detail .fail { background: #ffd8d8; }
77
78/* "start recording" controls*/
79#record_div { margin-top: 3em; }
80#record_div p { margin-bottom: 0.5em; }
81#record_select { width: 88%; }
82#record_input { width: 53%; }
83</style>
84<script type="text/javascript">
85<!--
86
87function report_results() {
88    req = false;
89    // branch for native XMLHttpRequest object
90    if(window.XMLHttpRequest && !(window.ActiveXObject)) {
91        try {
92            req = new XMLHttpRequest();
93        } catch(e) {
94            req = false;
95        }
96    // branch for IE/Windows ActiveX version
97    } else if(window.ActiveXObject) {
98        try {
99            req = new ActiveXObject("Msxml2.XMLHTTP");
100        } catch(e) {
101            try {
102                req = new ActiveXObject("Microsoft.XMLHTTP");
103            } catch(e) {
104                req = false;
105            }
106        }
107    } 
108    req.open("POST", "/test/results.cgi");
109    req.setRequestHeader("Content-Type", 'application/x-www-form-urlencoded');
110    var results = document.getElementById('total').innerHTML;
111    var test_text = "";
112    if (results.match("fail")) {
113        test_text = document.getElementById("results").innerHTML;
114    }   
115    req.send("results="+escape(results)+"&test_text="+escape(test_text));
116}
117
118if( typeof( Test )=="undefined" ) {
119        Test={};
120}
121Test.AnotherWay={};
122
123Test.AnotherWay._g_test_iframe=null; // frame where to load test pages
124Test.AnotherWay._g_test_frame_no_clear=false; // true - leave last page displayed after tests end
125Test.AnotherWay._g_test_page_urls=[]; // array of: { url: url, convention: "anotherway" or "jsan" }
126Test.AnotherWay._g_test_object_for_jsan=null; // test object for filling by tests that adhere to jsan Test.Simple calling convention
127Test.AnotherWay._g_pages_to_run=null; // list of pages to run automatically after loading
128Test.AnotherWay._g_run_on_main_load=false; // special handling for run_pages_to_run when it might be called before onload or before list of test pages is known.
129Test.AnotherWay._g_run_on_list_load=false;
130Test.AnotherWay._g_main_loaded=false;
131
132Test.AnotherWay._run_pages_to_run=function( called_from_outside )
133{
134        if( !Test.AnotherWay._g_main_loaded ) {
135                Test.AnotherWay._g_run_on_main_load=true;
136        }else {
137                var a_pages=Test.AnotherWay._g_pages_to_run;
138                if( a_pages=="all" ) {
139                        for( var i=0; i<Test.AnotherWay._g_test_page_urls.length; ++i ) {
140                                Test.AnotherWay._run_test_page( "test"+i );
141                        }
142                }else if( a_pages!=null ) {
143                        for( var run_i=0; run_i<a_pages.length; ++run_i ) {
144                                var run_page=a_pages[run_i];
145                                var found=false;
146                                for( var all_i=0; all_i<Test.AnotherWay._g_test_page_urls.length; ++all_i ) {
147                                        if( run_page==Test.AnotherWay._g_test_page_urls[all_i].url ) {
148                                                Test.AnotherWay._run_test_page( "test"+all_i, called_from_outside );
149                                                found=true;
150                                                break;
151                                        }
152                                }
153                                if( !found ) {
154                                        Test.AnotherWay._show_error( "page specified to run is not found in the page list: "+run_page );
155                                        break;
156                                }
157                        }
158                }
159        }
160}
161
162Test.AnotherWay._add_test_page_url=function( test_url, convention )
163{
164        var table=document.getElementById( "testtable" );
165        var record_select=document.getElementById( "record_select" );
166        var index=Test.AnotherWay._g_test_page_urls.length;
167
168        // trim spaces.
169        if( test_url.match( "^(\\s*)(.*\\S)(\\s*)$" ) ) {
170                test_url=RegExp.$2;
171        }
172
173        Test.AnotherWay._g_test_page_urls[index]={ url: test_url, convention: convention };
174        var row=table.insertRow( -1 );
175
176        var cell;
177        var cell_child;
178        cell=row.insertCell( -1 );
179        cell_child=document.createElement( "input" );
180        cell_child.type="checkbox";
181        cell_child.id="checkbox"+index;
182    cell_child.checked='checked';
183    cell_child.defaultChecked='checked';
184        cell.appendChild( cell_child );
185
186        cell=row.insertCell( -1 );
187        cell.setAttribute( "width", "75%" );
188        cell.appendChild( document.createTextNode( test_url ) );
189
190        cell=row.insertCell( -1 );
191        cell_child=document.createElement( "input" );
192        cell_child.type="button";
193        cell_child.id="test"+index;
194        cell_child.value=" run ";
195        cell_child.onclick=Test.AnotherWay._run_one_onclick;
196        cell.appendChild( cell_child );
197
198        cell=row.insertCell( -1 );
199        cell.setAttribute( "width", "8em" );
200        cell_child=document.createElement( "span" );
201        cell.appendChild( cell_child );
202
203        var option=document.createElement( "option" );
204        option.appendChild( document.createTextNode( test_url ) );
205        record_select.appendChild( option );
206}
207Test.AnotherWay._show_error=function( msg )
208{
209        var error_div=document.getElementById( "error" );
210        error_div.innerHTML="";
211        error_div.appendChild( document.createTextNode( msg ) );
212        error_div.style.display="block";
213}
214
215// read urls from the list in the html file inside the list_iframe
216// fill on-screen list with urls and "run" buttons, and fill the g_test_page_urls object.
217Test.AnotherWay._list_iframe_onload=function()
218{
219        if( window.frames.list_iframe!=null && window.frames.list_iframe.location!="" && window.frames.list_iframe.location!="about:blank" ) {
220                var list_doc=window.frames.list_iframe.document;
221                var list=list_doc.getElementById( "testlist" );
222                if( list!=null ) {
223                        for( var i=0; i<list.childNodes.length; ++i ) {
224                                var item=list.childNodes[i];
225                                if( item.nodeName=="LI" || item.nodeName=="li" ) {
226                                        var convention="anotherway";
227                                        if( Test.AnotherWay._get_css_class( item )=="jsan" ) {
228                                                convention="jsan";
229                                        }
230                                        Test.AnotherWay._add_test_page_url( item.innerHTML, convention );
231                                }
232                        }
233                        if( Test.AnotherWay._g_run_on_list_load ) {
234                                Test.AnotherWay._g_run_on_list_load=false;
235                                Test.AnotherWay._run_pages_to_run();
236                        }
237                }else {
238                        Test.AnotherWay._show_error( "no list with id 'testlist' in a list file "+window.frames.list_iframe.location );
239                }
240        }
241}
242
243Test.AnotherWay._map_checkboxes=function( f )
244{
245        var table=document.getElementById( "testtable" );
246        var checks=table.getElementsByTagName( "INPUT" );
247        for( var i=0; i<checks.length; ++i ) {
248                if( checks[i].type=="checkbox" && checks[i].id.match( /^checkbox(\d+)$/ ) ) {
249                        f( checks[i], RegExp.$1 );
250                }
251        }
252}
253Test.AnotherWay._run_all_onclick=function()
254{
255        Test.AnotherWay._map_checkboxes( function( c, id ) { Test.AnotherWay._run_test_page( "test"+id ); } );
256}
257Test.AnotherWay._run_selected_onclick=function()
258{
259        Test.AnotherWay._map_checkboxes( function( c, id ) { if( c.checked ) Test.AnotherWay._run_test_page( "test"+id ); } );
260}
261Test.AnotherWay._unselect_all_onclick=function()
262{
263        Test.AnotherWay._map_checkboxes( function( c, id ) { c.checked=false; } );
264}
265Test.AnotherWay._run_one_onclick=function()
266{
267        Test.AnotherWay._run_test_page( this.id );
268}
269
270// construct an object that will gather results of running one test function
271Test.AnotherWay._test_object_t=function( fun_name )
272{
273        this.name=fun_name; // name of the test function
274        this.n_plan=null; // planned number of assertions
275        this.n_ok=0; // # of ok assertions
276        this.n_fail=0; // # of failed assertions
277        this.exception=""; // if the function throwed an exception, it's its message
278        this.exception_stack=[]; // strings: function call stack from the exception
279        this.assertions=[]; // assertion results: array of { ok: 1 or 0, name: string }
280        this.wait_result_milliseconds=0; // how long to wait before collecting results from the test
281        this.second_wait_msg=null; // <p> status message (in addition to the page wait_msg)
282        this.delay_actions=[]; // array of actions to be perfomed after the test function returns
283                                //      action : { acton_kind: "call" | "window" | "replay"
284                                //                              when "call":            { call_fn call_delay_milliseconds } call_fn takes nothing
285                                //                              when "window" :         { wnd_url wnd_wnd wnd_fn wnd_timeout_milliseconds wnd_dont_close } wnd_fn takes wnd
286                                //                              wnen "replay" :         { replay_wnd replay_events replay_event_i replay_checkpoints } checkpoint_fn takes this, wnd
287                                //      }
288        this.delay_action_i=null; // index of delay action currently being performed
289        this.delay_prev_timer_time=0;   // for counting time while performing delay_actions
290        this.delay_current_milliseconds_left=0; // time left before the next action, runs down
291        this.delay_total_milliseconds_left=0;   // for indication: total estimated time for all actions, runs up and down
292}
293
294Test.AnotherWay._test_object_t.prototype.ok=function( cond, name )
295{
296        if( cond ) {
297                ++this.n_ok;
298                cond=1;
299        }else {
300                ++this.n_fail;
301                cond=0;
302        }
303        this.assertions.push( { ok: cond, name: name } );
304}
305Test.AnotherWay._test_object_t.prototype.fail=function( name )
306{
307        this.ok( false, name );
308}
309Test.AnotherWay._test_object_t.prototype.plan=function( n )
310{
311        this.n_plan=n;
312}
313Test.AnotherWay._test_object_t.prototype.wait_result=function( seconds )
314{
315        this.wait_result_milliseconds=1000*seconds;
316}
317Test.AnotherWay._eq_fail_msg=function( path, what, expected, got )
318{
319        return "eq: "+path+" "+what+" differ: got "+got+", but expected "+expected;
320}
321Test.AnotherWay._array_eq=function( expected, got, path, msg )
322{
323        if( expected.length!=got.length ) {
324                msg.msg=Test.AnotherWay._eq_fail_msg( path, "array length", expected.length, got.length );
325                return false;
326        }
327        for( var i=0; i<expected.length; ++i ) {
328                if( !Test.AnotherWay._thing_eq( expected[i], got[i], path+"["+i+"]", msg ) ) {
329                        return false;
330                }
331        }
332        return true;
333}
334Test.AnotherWay._object_eq=function( expected, got, path, msg )
335{
336        var v;
337        for( v in expected ) {
338                if( ! (v in got) ) {
339                        msg.msg=Test.AnotherWay._eq_fail_msg( path+"."+v, "properties", expected[v], "undefined" );
340                        return false;
341                }
342                if( !Test.AnotherWay._thing_eq( expected[v], got[v], path+"."+v, msg ) ) {
343                        return false;
344                }
345        }
346        for( v in got ) {
347                if( ! (v in expected) ) {
348                        msg.msg=Test.AnotherWay._eq_fail_msg( path+"."+v, "properties", "undefined", got[v] );
349                        return false;
350                }
351        }
352        return true;
353}
354Test.AnotherWay._constructor_name=function( x )
355{
356        if( x==null ) {
357                return "";
358        }
359        var s="unknown";
360        try {
361                s=typeof( x.constructor );
362                if( s!="unknown" ) {
363                        s=x.constructor.toString();
364                }
365        }catch( e ) {
366                s="unknown";
367        }
368        if( s=="unknown" ) {
369                // hackish attempt to guess a type
370                var is_array=true;
371                var index=0;
372                for( i in x ) {
373                        if( i!=index ) {
374                                is_array=false;
375                        }
376                        ++index;
377                }
378                return is_array ? "Array" : "Object"; // for empty arrays/objects, this will be wrong half the time
379        }else if( s.match( /^\s*function\s+(\w+)\s*\(/ ) ) {
380                return RegExp.$1;
381        }else {
382          var c = '';
383          switch(typeof x) {
384            case 'string':
385              c = 'String';
386              break;
387            case 'object':
388              c = 'Object';
389              break;
390            default:
391              c = '';
392          }
393                return c;       }
394}
395Test.AnotherWay._is_array=function( x )
396{
397        return Test.AnotherWay._constructor_name( x )=="Array";
398}
399Test.AnotherWay._is_value_type=function( x )
400{
401        cn=Test.AnotherWay._constructor_name( x );
402        return cn=="Number" || cn=="String" || cn=="Boolean" || cn=="Date";
403}
404Test.AnotherWay._thing_eq=function( expected, got, path, msg )
405{
406        if( expected==null && got==null ) {
407                return true;
408        }else if( (expected==null && got!=null) || (expected!=null && got==null) ) {
409                msg.msg=Test.AnotherWay._eq_fail_msg( path, "values", expected, got );
410                return false;
411        }else {
412                var expected_cn=Test.AnotherWay._constructor_name( expected );
413                var got_cn=Test.AnotherWay._constructor_name( got );
414                if( expected_cn!=got_cn ) {
415                        msg.msg=Test.AnotherWay._eq_fail_msg( path, "types", expected_cn, got_cn );
416                        return false;
417                }else {
418                        if( Test.AnotherWay._is_array( expected ) ) {
419                                return Test.AnotherWay._array_eq( expected, got, path, msg );
420                        }else if( Test.AnotherWay._is_value_type( expected ) ) {
421                                if( expected!=got ) {
422                                        msg.msg=Test.AnotherWay._eq_fail_msg( path, "values", expected, got );
423                                        return false;
424                                }else {
425                                        return true;
426                                }
427                        }else { // just a plain object
428                                return Test.AnotherWay._object_eq( expected, got, path, msg );
429                        }
430                }
431        }
432}
433Test.AnotherWay._test_object_t.prototype.eq=function( got, expected, name )
434{
435        var msg={};
436        if( Test.AnotherWay._thing_eq( expected, got, "", msg ) ) {
437                this.ok( 1, name );
438        }else {
439                this.fail( name+". "+msg.msg );
440        }
441}
442Test.AnotherWay._test_object_t.prototype.like=function( got, expected, name )
443{
444        if( got.match( expected )!=null ) {
445                this.ok( 1, name );
446        }else {
447                this.fail( name+": got "+got+", but expected it to match: "+expected );
448        }
449}
450Test.AnotherWay._g_html_eq_span=null;
451Test.AnotherWay._html_eq_string_to_node=function( string_or_node, what, msg )
452{
453        if( string_or_node.nodeType!=null ) {
454                string_or_node=Test.AnotherWay._html_eq_node_to_string( string_or_node ); // double trip - to make properties assigned in scripts available as html node attributes
455        }
456        if( Test.AnotherWay._g_html_eq_span==null ) {
457                Test.AnotherWay._g_html_eq_span=document.createElement( "span" );
458        }
459        Test.AnotherWay._g_html_eq_span.innerHTML=string_or_node;
460        if( Test.AnotherWay._g_html_eq_span.childNodes.length!=1 ) {
461                msg.msg="bad "+what+" html string given (should contain exactly one outermost element): "+string_or_node;
462        }
463        return Test.AnotherWay._g_html_eq_span.childNodes[0].cloneNode( true );
464}
465Test.AnotherWay._html_eq_node_to_string=function( node ) {
466        if( Test.AnotherWay._g_html_eq_span==null ) {
467                Test.AnotherWay._g_html_eq_span=document.createElement( "span" );
468        }
469        Test.AnotherWay._g_html_eq_span.innerHTML="";
470        if( node.outerHTML!=null ) {
471                Test.AnotherWay._g_html_eq_span.innerHTML=node.outerHTML;
472        }else {
473            var clone = node.cloneNode(true);
474            var node = Test.AnotherWay._g_html_eq_span;
475            if(node.ownerDocument && node.ownerDocument.importNode) {
476                if(node.ownerDocument != clone.ownerDocument) {
477                    clone = node.ownerDocument.importNode(clone, true);
478                }
479            }
480            node.appendChild(clone);
481        }
482        return Test.AnotherWay._g_html_eq_span.innerHTML;
483}
484Test.AnotherWay._html_eq_path_msg=function( path )
485{
486        var msg="";
487        for( var i=0; i<path.length; ++i ) {
488                msg+=" [node "+path[i].node;
489                if( path[i].id!=null && path[i].id!="" ) {
490                        msg+=" id "+path[i].id;
491                }else if( path[i].index!=null ) {
492                        msg+=" at index "+path[i].index;
493                }
494                msg+="] "
495        }
496        return msg;
497}
498Test.AnotherWay._html_eq_fail_msg=function( path, what, expected, got )
499{
500        return Test.AnotherWay._html_eq_path_msg( path )+": "+what+" differ: got "+got+", but expected "+expected;
501}
502Test.AnotherWay._html_eq_remove_blank=function( text )
503{
504        if( text==null ) {
505                return "";
506        }else if( text.match( "^(\\s*)(.*\\S)(\\s*)$" ) ) {
507                return RegExp.$2;
508        }else if( text.match( "\s*" ) ) {
509                return "";
510        }
511        return text;
512}
513Test.AnotherWay._html_eq_remove_blank_nodes=function( node )
514{
515        var to_remove=[];
516        for( var child=node.firstChild; child!=null; child=child.nextSibling ) {
517                if( child.nodeType==3 ) {
518                        var value=Test.AnotherWay._html_eq_remove_blank( child.nodeValue );
519                        if( value=="" ) {
520                                to_remove.push( child );
521                        }else {
522                                child.nodeValue=value;
523                        }
524                }
525        }
526        for( var i=0; i<to_remove.length; ++i ) {
527                node.removeChild( to_remove[i] );
528        }
529}
530Test.AnotherWay._html_node_type_text=function( node_type )
531{
532        if( node_type==1 ) {
533                return "1 (html element)";
534        }else if( node_type==3 ) {
535                return "3 (text)";
536        }else {
537                return node_type;
538        }
539}
540Test.AnotherWay._html_eq_node=function( expected, got, path, msg, expected_loc_base, got_loc_base )
541{
542        if( expected.nodeType!=got.nodeType ) {
543                msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "node types", Test.AnotherWay._html_node_type_text( expected.nodeType ), Test.AnotherWay._html_node_type_text( got.nodeType ) );
544                return false;
545        }else if( expected.nodeType==3 ) {
546                if( expected.nodeValue!=got.nodeValue ) {
547                        msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "text", expected.nodeValue, got.nodeValue );
548                        return false;
549                }
550        }else if( expected.nodeType==1 ) {
551                if( expected.nodeName!=got.nodeName ) {
552                        msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "node names", expected.nodeName, got.nodeName );
553                        return false;
554                }
555                // compare attributes
556                var expected_attrs={};
557                var got_attrs={};
558                var i;
559                var a;
560                for( i=0; i<expected.attributes.length; ++i ) {
561                        a=expected.attributes[i];
562                        if( a.specified ) {
563                                expected_attrs[a.name]=1;
564                        }
565                }
566                for( i=0; i<got.attributes.length; ++i ) {
567                        a=got.attributes[i];
568                        if( a.specified ) {
569                                got_attrs[a.name]=1;
570                        }
571                }
572                for( a in expected_attrs ) {
573                        if( ! (a in got_attrs) ) {
574                                msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": attribute sets differ: expected attribute "+a+" is missing";
575                                return false;
576                        }
577                }
578                for( a in got_attrs ) {
579                        if( ! (a in expected_attrs) ) {
580                                msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": attribute sets differ: got extra attribute "+a;
581                                return false;
582                        }
583                }
584                for( a in expected_attrs ) {
585                        var expected_value=expected.getAttribute( a );
586                        var got_value=got.getAttribute( a );
587                        if( typeof( expected_value )=="string" && typeof( got_value )=="string" ) {
588                                expected_value=Test.AnotherWay._html_eq_remove_blank( expected_value );
589                                got_value=Test.AnotherWay._html_eq_remove_blank( got_value );
590                                var ok=expected_value==got_value;
591                                if( !ok && (a=="href" || a=="HREF" )  ) { // try relative hrefs
592                                        var expected_relative_value=expected_value;
593                                        if( expected_loc_base!=null && expected_value.substring( 0, expected_loc_base.length )==expected_loc_base ) {
594                                                expected_relative_value=expected_value.substring( expected_loc_base.length );
595                                        }
596                                        var got_relative_value=got_value;
597                                        if( got_loc_base!=null && got_value.substring( 0, got_loc_base.length )==got_loc_base ) {
598                                                got_relative_value=got_value.substring( got_loc_base.length );
599                                        }
600                                        ok=expected_relative_value==got_relative_value;
601                                }
602                                if( !ok ) {
603                                        msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "attribute "+a+" values", expected_value, got_value );
604                                        return false;
605                                }
606                        }else if( typeof( expected_value )=="function" && typeof( got_value )=="function" ) {
607                                expected_value=expected_value.toString();
608                                got_value=got_value.toString();
609                                if( expected_value!=got_value ) {
610                                        msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "attribute "+a+" values", expected_value, got_value );
611                                        return false;
612                                }
613                        }else {
614                                var value_msg={};
615                                if( !Test.AnotherWay._thing_eq( expected_value, got_value, "", value_msg ) ) {
616                                        msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": attribute "+a+" values differ: "+value_msg.msg;
617                                        return false;
618                                }
619                        }
620                }
621                // compare child nodes
622                Test.AnotherWay._html_eq_remove_blank_nodes( expected );
623                Test.AnotherWay._html_eq_remove_blank_nodes( got );
624                var expected_length=expected.childNodes.length;
625                var got_length=got.childNodes.length;
626                if( expected_length<got_length ) {
627                        msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": got "+(got_length-expected_length)+" extra child nodes";
628                        return false;
629                }else if( expected_length>got_length ) {
630                        msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": expected "+(expected_length-got_length)+" more child nodes";
631                        return false;
632                }else {
633                        for( i=0; i<expected_length; ++i ) {
634                                var expected_node=expected.childNodes[i];
635                                path.push( { node: expected_node.nodeName, id: expected_node.id, index: i } );
636                                var eq=Test.AnotherWay._html_eq_node( expected_node, got.childNodes[i], path, msg, expected_loc_base, got_loc_base );
637                                path.pop();
638                                if( !eq ) {
639                                        return false;
640                                }
641                        }
642                }
643        }
644        return true;
645}
646Test.AnotherWay._html_eq_get_loc_base=function( node )
647{
648        var loc_base=document.location;
649        if( node.ownerDocument!=null ) {
650                loc_base=node.ownerDocument.location;
651        }
652        if( loc_base!=null ) {
653                loc_base=loc_base.href;
654                var slash_pos=loc_base.lastIndexOf( "/" );
655                if( slash_pos!=-1 ) {
656                        loc_base=loc_base.substring( 0, slash_pos+1 );
657                }
658        }
659        return loc_base;
660}
661Test.AnotherWay._test_object_t.prototype.html_eq=function( got, expected, name )
662{
663        var msg={};
664        var expected_node=Test.AnotherWay._html_eq_string_to_node( expected, "expected", msg );
665        if( msg.msg!=null ) {
666                this.fail( name+" html_eq: "+msg.msg );
667        }else {
668                var got_node=Test.AnotherWay._html_eq_string_to_node( got, "got", msg );
669                if( msg.msg!=null ) {
670                        this.fail( name+" html_eq: "+msg.msg );
671                }else {
672                        var expected_loc_base=Test.AnotherWay._html_eq_get_loc_base( expected );
673                        var got_loc_base=Test.AnotherWay._html_eq_get_loc_base( got );
674                        if( Test.AnotherWay._html_eq_node( expected_node, got_node, [], msg, expected_loc_base, got_loc_base ) ) {
675                                this.ok( 1, name );
676                        }else {
677                                var msg=name+" html_eq "+msg.msg;
678                                var expected_str=Test.AnotherWay._html_eq_node_to_string( expected_node );
679                                var got_str=Test.AnotherWay._html_eq_node_to_string( got_node );
680                                msg+=".\n got html: "+got_str;
681                                msg+=".\n expected html: "+expected_str;
682                                this.fail( msg );
683                        }
684                }
685        }
686}
687Test.AnotherWay._debug_pane_print=function( msg )
688{
689        var d=new Date();
690        var p=document.createElement( "p" );
691        p.appendChild( document.createTextNode( d.toLocaleTimeString()+" "+msg ) );
692        var debug_pane=document.getElementById( "debug" );
693        debug_pane.appendChild( p );
694        var debug_tab=document.getElementById( "debug_tab" );
695        var results_tab=document.getElementById( "results_tab" );
696        debug_tab.style.visibility="visible";
697        results_tab.style.visibility="visible";
698}
699Test.AnotherWay._test_object_t.prototype.debug_print=function( msg )
700{
701        Test.AnotherWay._debug_pane_print( this.name+": "+msg );
702}
703Test.AnotherWay._test_object_t.prototype.delay_call=function()
704{
705        var timeout_ms=200;
706        for( var i=0; i<arguments.length; ++i ) {
707                if( typeof( arguments[i] )!="function" ) {
708                        timeout_ms=3000*arguments[i];
709                }else {
710                        var action={ action_kind: "call", call_delay_milliseconds: timeout_ms, call_fn: arguments[i] };
711                        this.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );
712                        this.delay_actions.push( action );
713                }
714        }
715}
716Test.AnotherWay._test_object_t.prototype.open_window=function( url, fn, timeout_seconds )
717{
718        if( timeout_seconds==null ) {
719                timeout_seconds=4;
720        }
721        var no_close=document.getElementById( "dont_close_test_windows" );
722        var action={ action_kind: "window", wnd_url: url.toString(), wnd_wnd: null, wnd_fn: fn, wnd_timeout_milliseconds: timeout_seconds*1000, wnd_no_close: no_close.checked };
723        this.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );
724        this.delay_actions.push( action );
725}
726Test.AnotherWay._test_object_t.prototype.replay_events=function( wnd, events )
727{
728        if( Test.AnotherWay._g_no_record_msg!=null ) {
729                this.fail( "replay_events: "+Test.AnotherWay._g_no_record_msg );
730        }else {
731                var action={ action_kind: "replay", replay_wnd: wnd, replay_events: events.events, replay_event_i: null, replay_checkpoints: events.checkpoints };
732                this.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );
733                this.delay_actions.push( action );
734        }
735}
736Test.AnotherWay._action_estimate_milliseconds=function( action )
737{
738        var ms=0;
739        if( action.action_kind=="call" ) {
740                ms=action.call_delay_milliseconds;
741        }else if( action.action_kind=="window" ) {
742                ms=0;
743        }else if( action.action_kind=="replay" ) {
744                ms=0;
745                for( var i=0; i<action.replay_events.length; ++i ) {
746                        ms+=action.replay_events[i]["time"]-0;
747                }
748        }
749        return ms;
750}
751
752Test.AnotherWay._g_timeout_granularity=200;
753Test.AnotherWay._g_tests_queue=[]; // vector of { url: string, test_objects : array of test_object_t, test_object_i: int, wait_msg: <p> object, loading_timeout_milliseconds: int, timeout_id: id }
754
755// load one html page, schedule further processing
756Test.AnotherWay._run_test_page=function( id, called_from_outside )
757{
758        if( id.match( /^test(\d+)/ ) ) {
759                id=RegExp.$1;
760                Test.AnotherWay._g_tests_queue.push( {
761                        url: Test.AnotherWay._g_test_page_urls[id].url,
762                        convention: Test.AnotherWay._g_test_page_urls[id].convention,
763                        test_objects: []
764                        } );
765                if( Test.AnotherWay._g_tests_queue.length==1 ) {
766                        if( !called_from_outside ) {
767                                // Crap. Be careful stepping around.
768                                // For Mozilla and Opera, when this file is included into the frameset page that is in another directory (and _g_outside_path_correction!=null)
769                                // but the test pages are started from within it (by "run" buttons), then:
770                                // depending on whether the page is the first one loaded into the test frame or not,
771                                // the base url for relative test pages differs.
772                                // Crap, like I said.
773                                Test.AnotherWay._g_tests_queue[0].suppress_outside_path_correction=true;
774                        }
775                        Test.AnotherWay._start_loading_page();
776                }
777        }
778}
779Test.AnotherWay._load_next_page=function()
780{
781        Test.AnotherWay._g_tests_queue.splice( 0, 1 );
782        if( Test.AnotherWay._g_tests_queue.length>0 ) {
783                Test.AnotherWay._start_loading_page();
784        }else {
785                if( !Test.AnotherWay._g_test_frame_no_clear ) {
786                        Test.AnotherWay._g_test_iframe.location.replace( "about:blank" );
787                }
788        report_results();
789    }
790}
791Test.AnotherWay._g_opera_path_correction=null; // ugly wart to support opera
792Test.AnotherWay._g_outside_path_correction=null; // ugly wart to accomodate Opera and Mozilla, where relative url relates to the directory where the page that calls this function is located
793Test.AnotherWay._set_iframe_location=function( iframe, loc, outside_path_correction )
794{
795        // allow to load only locations with the same origin
796        var proto_end=loc.indexOf( "://" );
797        if( proto_end!=-1 ) { // otherwise, it's safe to assume (for Opera, Mozilla and IE ) that loc will be treated as relative
798                var main_loc=window.location.href;
799                var host_end=loc.substring( proto_end+3 ).indexOf( "/" );
800                var ok=false;
801                if( host_end!=-1 ) {
802                        var loc_origin=loc.substring( 0, proto_end+3+host_end+1 );
803                        if( main_loc.length>=loc_origin.length && main_loc.substring( 0, loc_origin.length )==loc_origin ) {
804                                ok=true;
805                        }
806                }
807                if( !ok ) {
808                        return { msg: "test pages may have only urls with the same origin as "+main_loc };
809                }
810        }
811        // opera cannot handle urls relative to file:// without assistance
812        if( window.opera!=null && window.location.protocol=="file:" && loc.indexOf( ":" )==-1 ) {
813                var base=window.location.href;
814                var q_pos=base.indexOf( "?" );
815                if( q_pos!=-1 ) {
816                        base=base.substring( 0, q_pos );
817                }
818                var slash_pos=base.lastIndexOf( "/" );
819                if( slash_pos!=-1 ) {
820                        base=base.substring( 0, slash_pos+1 );
821                        Test.AnotherWay._g_opera_path_correction=base;
822                        loc=base+loc;
823                }
824        }
825        // if this function is called from another page, and if that page is in another directory, correction is needed
826        if( outside_path_correction!=null ) {
827                var pos=loc.indexOf( outside_path_correction );
828                if( pos==0 ) {
829                        loc=loc.substring( outside_path_correction.length+1 );
830                }
831        }
832        if( iframe.location!=null ) {
833                iframe.location.replace( loc );
834        }else {
835                iframe.src=loc;
836        }
837        return {};
838}
839Test.AnotherWay._start_loading_page=function()
840{
841        var test_page=Test.AnotherWay._g_tests_queue[0];
842        test_page.loading_timeout_milliseconds=20000;
843        test_page.timeout_id=setTimeout( Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity );
844        test_page.wait_msg=Test.AnotherWay._print_counter_result( test_page.url, "loading...", test_page.loading_timeout_milliseconds, "loading" );
845        if( test_page.convention=="jsan" ) {
846                // the tests in that page will run when it's loading, so the test object must be ready
847                Test.AnotherWay._g_test_object_for_jsan=new Test.AnotherWay._test_object_t( test_page.url );
848        }
849        var outside_path_correction=null;
850        if( Test.AnotherWay._g_outside_path_correction!=null && !test_page.suppress_outside_path_correction ) {
851                outside_path_correction=Test.AnotherWay._g_outside_path_correction;
852        }
853        var result=Test.AnotherWay._set_iframe_location( Test.AnotherWay._g_test_iframe, test_page.url, outside_path_correction );
854        if( result.msg!=null ) {
855                Test.AnotherWay._unprint_result( test_page.wait_msg );
856                Test.AnotherWay._print_result( test_page.url, result.msg, "badtest", null );
857                Test.AnotherWay._load_next_page();
858        }
859}
860
861Test.AnotherWay._loading_timeout=function()
862{
863        var test_page=Test.AnotherWay._g_tests_queue[0];
864        test_page.loading_timeout_milliseconds-=Test.AnotherWay._g_timeout_granularity;
865        if( test_page.loading_timeout_milliseconds>0 ) {
866                Test.AnotherWay._update_msg_counter( test_page.wait_msg, (test_page.loading_timeout_milliseconds/1000).toFixed() );
867                test_page.timeout_id=setTimeout( Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity );
868        }else {
869                Test.AnotherWay._unprint_result( test_page.wait_msg );
870                Test.AnotherWay._print_result( test_page.url, "Unable to load test page. Timeout expired", "badtest", null );
871                Test.AnotherWay._load_next_page();
872        }
873}
874
875Test.AnotherWay._strip_query_and_hash=function( s )
876{
877        var i=s.lastIndexOf( "#" );
878        if( i!=-1 ) {
879                s=s.substring( 0, i );
880        }
881        i=s.lastIndexOf( "?" );
882        if( i!=-1 ) {
883                s=s.substring( 0, i );
884        }
885        return s;
886}
887Test.AnotherWay._is_url_loaded=function( url, wnd )
888{
889        var loaded=false;
890        if( wnd!=null && wnd.location!=null ) {
891                // after some popup blocker interference, location may behave strange..
892                var location_s="";
893                location_s+=wnd.location;
894                if( location_s!="" ) {
895                        var pathname=wnd.location.pathname;
896                        var expected_url=url;
897                        var i=expected_url.lastIndexOf( "#" );
898                        if( i!=-1 ) {
899                                expected_url=expected_url.substring( 0, i );
900                        }
901                        i=expected_url.lastIndexOf( "?" );
902                        if( i!=-1 ) {
903                                expected_url=expected_url.substring( 0, i );
904                        }
905                        i=expected_url.lastIndexOf( "/" );
906                        if( i!=-1 && i!=expected_url.length-1 ) {
907                                expected_url=expected_url.substring( i+1 );
908                        }
909                        i=pathname.indexOf( expected_url )
910                        if( wnd.location.href==url || (i!=-1 && i==pathname.length-expected_url.length) ) {
911                                if( /*window.opera==null*/wnd.document.readyState==null || wnd.document.readyState=="complete" ) { // for opera (and IE?), getElementById does not work until..
912                                        loaded=true;
913                                }
914                        }
915                }
916        }
917        return loaded;
918}
919// find and run all test functions in the g_cur_page html page.
920Test.AnotherWay._test_page_onload=function()
921{
922        if( Test.AnotherWay._g_tests_queue.length==0 ) {
923                return;
924        }
925        var test_page=Test.AnotherWay._g_tests_queue[0];
926        if( !Test.AnotherWay._is_url_loaded( test_page.url, Test.AnotherWay._g_test_iframe ) ) {
927                return;
928        }
929        clearTimeout( test_page.timeout_id );
930        Test.AnotherWay._unprint_result( test_page.wait_msg );
931
932        if( test_page.convention=="anotherway" ) {
933                // get test function names (those beginning with "test")
934                if( typeof( Test.AnotherWay._g_test_iframe.document.scripts )!='undefined' ) { // IE
935                        for( var i=0; i<Test.AnotherWay._g_test_iframe.document.scripts.length; ++i ) {
936                                var script_text=Test.AnotherWay._g_test_iframe.document.scripts[i].text;
937                                var fun_sig="function test";
938                                var fun_start=script_text.indexOf( fun_sig );
939
940                                while( fun_start!=-1 ) {
941                                        script_text=script_text.substring( fun_start, script_text.length );
942                                        var fun_end=script_text.indexOf( '(' );
943                                        var fun_name=script_text.substring( "function ".length,  fun_end );
944                                        var whitespace = fun_name.indexOf( ' ' );
945                                        if (whitespace >= 0)
946                                            fun_name = fun_name.substring( 0, whitespace );
947                                        test_page.test_objects.push( new Test.AnotherWay._test_object_t( fun_name ) );
948                                        script_text=script_text.substring( fun_end, script_text.length );
949                                        fun_start=script_text.indexOf( fun_sig  );
950                                }
951                        }
952                }else { // otherwise (not IE) it ought to work like this
953                        for( var i in Test.AnotherWay._g_test_iframe) {
954                                // Hack to prevent failure in FF3.0b1
955                if (i == "innerWidth" || i == "innerHeight") { continue; }
956                                if( typeof( Test.AnotherWay._g_test_iframe[i] )=='function' ) {
957                                        if( i.substring( 0, 4 )=="test" ) {
958                                                test_page.test_objects.push( new Test.AnotherWay._test_object_t( i ) );
959                                        }
960                                }
961                        }
962                }
963        }else if( test_page.convention=="jsan" ) {
964                // the test object is already filled with results
965                test_page.test_objects.push( Test.AnotherWay._g_test_object_for_jsan );
966        }
967
968        if( test_page.test_objects.length==0 ) {
969                Test.AnotherWay._print_result( test_page.url,  "No test functions defined in the page", "badtest", null );
970                Test.AnotherWay._load_next_page();
971                return;
972        }
973
974        test_page.wait_msg=Test.AnotherWay._print_result( test_page.url, "running tests..<span class=\"counter\">"+test_page.test_objects.length+"</span>", "running", null );
975
976        test_page.test_object_i=0;
977        Test.AnotherWay._run_more_tests();
978}
979
980Test.AnotherWay._handle_exception=function( o, e, title )
981{
982        var s=title+": "+typeof( e )+": ";
983        if( e.message!=null ) {
984                s+=e.message;
985        }else if( e.description!=null ) {
986                s+=e.description;
987        }else {
988                s+=e.toString();
989        }
990//      if( e.location!=null ) {  // XXX figure out how to display exception location if it's present (like in mozilla)
991//              s+=" location: "+e.location.toString();
992//      }
993        o.exception=s;
994        s=[];
995        if( e.stack ) {
996                var lines=e.stack.split( "\n" );
997                for( var i=0; i<lines.length; ++i ) {
998                        // format of the line: func_name(args)@file_name:line_no
999                        if( lines[i].match( /(\w*)\(([^\)]*)\)@(.*):([^:]*)$/ ) ) {
1000                                var func_name=RegExp.$1;
1001                                if( func_name.length==0 ) {
1002                                        func_name="<anonymous>";
1003                                }
1004                                s.push( "in "+func_name+"( "+RegExp.$2+") at "+RegExp.$3+" line "+RegExp.$4+"\n" );
1005                        }
1006                }
1007        }
1008        o.exception_stack=s;
1009}
1010
1011Test.AnotherWay._run_more_tests=function()
1012{
1013        var test_page=Test.AnotherWay._g_tests_queue[0];
1014        while( test_page.test_object_i<test_page.test_objects.length ) {
1015                Test.AnotherWay._update_msg_counter( test_page.wait_msg, (1+test_page.test_object_i)+"/"+test_page.test_objects.length );
1016                var o=test_page.test_objects[test_page.test_object_i];
1017                if( test_page.convention=="anotherway" ) {
1018                        try {
1019                                Test.AnotherWay._g_test_iframe[o.name]( o );
1020                        }catch( e ) {
1021                                Test.AnotherWay._handle_exception( o, e, "" );
1022                        }
1023                } // for "jsan" convention, test has run already
1024                if( o.delay_actions.length>0 || o.wait_result_milliseconds>0 ) {
1025                        o.delay_total_milliseconds_left+=o.wait_result_milliseconds;
1026                        Test.AnotherWay._delay_actions_timeout();
1027                        return;
1028                }
1029                ++test_page.test_object_i;
1030        }
1031        Test.AnotherWay._unprint_result( test_page.wait_msg );
1032        Test.AnotherWay._print_result( test_page.url, null, null, test_page.test_objects );
1033        Test.AnotherWay._load_next_page();
1034}
1035
1036Test.AnotherWay._delay_actions_timeout=function()
1037{
1038        var test_page=Test.AnotherWay._g_tests_queue[0];
1039        var test_object=test_page.test_objects[test_page.test_object_i];
1040        var finished=true;
1041        if( test_object.delay_action_i==null ) {
1042                // set up to start first action
1043                test_object.delay_action_i=-1;
1044        }else {
1045                // perform current action
1046                var milliseconds_passed=(new Date()).getTime()-test_object.delay_prev_timer_time;
1047                test_object.delay_current_milliseconds_left-=milliseconds_passed;
1048                test_object.delay_total_milliseconds_left-=milliseconds_passed;
1049                finished=Test.AnotherWay._delay_continue_action( test_object, milliseconds_passed );
1050        }
1051        while( finished && test_object.delay_action_i<test_object.delay_actions.length ) {
1052                ++test_object.delay_action_i; // start next action
1053                finished=Test.AnotherWay._delay_start_action( test_object );
1054        }
1055        if( test_object.delay_action_i<=test_object.delay_actions.length ) { // any more actions left ?
1056                test_object.delay_prev_timer_time=(new Date()).getTime();
1057                var next_timeout=Test.AnotherWay._g_timeout_granularity;
1058                if( test_object.delay_current_milliseconds_left<next_timeout ) {
1059                        next_timeout=test_object.delay_current_milliseconds_left;
1060                }
1061                if( test_object.second_wait_msg!=null ) {
1062                        Test.AnotherWay._update_msg_counter( test_object.second_wait_msg, (test_object.delay_total_milliseconds_left/1000).toFixed() );
1063                }
1064                setTimeout( Test.AnotherWay._delay_actions_timeout, next_timeout );
1065        }else { // no more actions left. run the next test.
1066                if( test_object.second_wait_msg!=null ) {
1067                        Test.AnotherWay._unprint_result( test_object.second_wait_msg );
1068                        test_object.second_wait_msg=null;
1069                }
1070                ++test_page.test_object_i;
1071                Test.AnotherWay._run_more_tests();
1072        }
1073}
1074Test.AnotherWay._delay_start_action=function( test_object )
1075{
1076        var finished=false;
1077        var wait_msg="";
1078        if( test_object.delay_action_i==test_object.delay_actions.length ) {
1079                if( test_object.wait_result_milliseconds>0 ) {
1080                        test_object.delay_current_milliseconds_left=test_object.wait_result_milliseconds; // wait for result
1081                        wait_msg="waiting for results..";
1082                }else {
1083                        ++test_object.delay_action_i; // dont wait for result
1084                }
1085        }else {
1086                var action=test_object.delay_actions[test_object.delay_action_i];
1087                if( action.action_kind=="call" ) {
1088                        test_object.delay_current_milliseconds_left=action.call_delay_milliseconds;
1089                        wait_msg="performing delayed calls..";
1090                }else if( action.action_kind=="window" ) {
1091                        if( Test.AnotherWay._g_opera_path_correction!=null && action.wnd_url.indexOf( ":" )==-1 ) {
1092                                action.wnd_url=Test.AnotherWay._g_opera_path_correction+action.wnd_url;
1093                        }
1094                        action.wnd_wnd=window.open( action.wnd_url, "_blank" );
1095                        if( action.wnd_wnd==null ) {
1096                                finished=true;
1097                                test_object.fail( "unable to open window for "+action.wnd_url );
1098                        }else {
1099                                test_object.delay_current_milliseconds_left=action.wnd_timeout_milliseconds;
1100                                wait_msg="opening window..";
1101                        }
1102                }else if( action.action_kind=="replay" ) {
1103                        if( action.replay_events.length==0 ) {
1104                                finished=true;
1105                        }else {
1106                                action.replay_event_i=0;
1107                                test_object.delay_current_milliseconds_left=action.replay_events[0]["time"];
1108                                wait_msg="replaying events..";
1109                        }
1110                }
1111        }
1112        if( test_object.second_wait_msg!=null ) {
1113                Test.AnotherWay._unprint_result( test_object.second_wait_msg );
1114        }
1115        if( wait_msg!="" ) {
1116                var test_page=Test.AnotherWay._g_tests_queue[0];
1117                test_object.second_wait_msg=Test.AnotherWay._print_counter_result( test_page.url, wait_msg, test_object.delay_total_milliseconds_left, "waiting" );
1118        }else {
1119                test_object.second_wait_msg=null;
1120        }
1121        return finished;
1122}
1123Test.AnotherWay._delay_continue_action=function( test_object, milliseconds_passed )
1124{
1125        var finished=test_object.delay_current_milliseconds_left<=0;
1126        if( test_object.delay_action_i==test_object.delay_actions.length ) { // action is "waiting for results"
1127                if( test_object.n_plan!=null && test_object.n_plan==test_object.n_ok+test_object.n_fail ) {
1128                        finished=true; // if all assertions results are recorded, don't wait any more
1129                }
1130                if( finished ) {
1131                        ++test_object.delay_action_i; // move on to the next test
1132                }
1133        }else {
1134                var action=test_object.delay_actions[test_object.delay_action_i];
1135                if( action.action_kind=="call" ) {
1136                        if( finished ) {
1137                                try {
1138                                        action.call_fn();
1139                                }catch( e ) {
1140                                        Test.AnotherWay._handle_exception( test_object, e, "in delay_call" );
1141                                }
1142                        }
1143                }else if( action.action_kind=="window" ) {
1144                        test_object.delay_total_milliseconds_left+=milliseconds_passed; // for "window", the countdown is suspended since it's unknown how long it will take
1145                        if( Test.AnotherWay._is_url_loaded( action.wnd_url, action.wnd_wnd ) ) {
1146                                try {
1147                                        action.wnd_fn( action.wnd_wnd );
1148                                }catch( e ) {
1149                                        Test.AnotherWay._handle_exception( test_object, e, "in open_window function call" );
1150                                }
1151                                finished=true;
1152                        }else if( finished ) {
1153                                test_object.fail(  "unable to open window for url '"+action.wnd_url+"'. timeout expired" );
1154                        }
1155                }else if( action.action_kind=="replay" ) {
1156                        if( finished ) {
1157//                              try {
1158                                        Test.AnotherWay._delay_replay_event( test_object, action.replay_wnd, action.replay_events[action.replay_event_i], action.replay_checkpoints );
1159//                              }catch( e ) { // disabled, until I know how to gel location info from an exception
1160//                                      Test.AnotherWay._handle_exception( test_object, e, "while replaying event" );
1161//                              }
1162                                ++action.replay_event_i;
1163                                finished=action.replay_event_i==action.replay_events.length;
1164                                if( !finished ) {
1165                                        test_object.delay_current_milliseconds_left=action.replay_events[action.replay_event_i]["time"];
1166                                }
1167                        }
1168                }
1169        }
1170        return finished;
1171}
1172Test.AnotherWay._delay_replay_event=function( test_object, wnd, event, checkpoints )
1173{
1174        if( event.type=="_checkpoint" ) {
1175                var checkpoint_n=event.which;
1176                var prev_n_fail=test_object.n_fail;
1177                checkpoints[checkpoint_n]( test_object, wnd );
1178                var flash_color= prev_n_fail==test_object.n_fail ? "#2f2" : "#f22" ;
1179                Test.AnotherWay._record_flash_border( flash_color );
1180        }else if( event.type=="click" || event.type=="mouseover" || event.type=="mouseout" || event.type=="mousemove" || event.type=="mousedown" || event.type=="mouseup" ) {
1181                var target=Test.AnotherWay._record_node_path_to_node( event["target"], wnd.document );
1182                if( target!=null ) {
1183                        Test.AnotherWay._record_control_update_highlight( target, "ball", event );
1184                        var e=wnd.document.createEvent( "MouseEvents" );
1185                        var related_target=Test.AnotherWay._record_node_path_to_node( event["relatedTarget"], wnd.document );
1186                        e.initMouseEvent(
1187                                event["type"],
1188                                event["cancelable"],
1189                                event["bubbles"],
1190                                wnd.document.defaultView,
1191                                event["detail"],
1192                                event["screenX"],
1193                                event["screenY"],
1194                                event["clientX"],
1195                                event["clientY"],
1196                                event["ctrlKey"],
1197                                event["altKey"],
1198                                event["shiftKey"],
1199                                event["metaKey"],
1200                                event["button"],
1201                                Test.AnotherWay._record_node_path_to_node( event["relatedTarget"], wnd.document )
1202                        );
1203                        // Firefox 1.0.6 somehow loses relatedTarget somewhere on the way. Pass through our own, for those who choose to care.
1204                        e.passThroughRelatedTarget=related_target;
1205                        target.dispatchEvent( e );
1206                }
1207        }else if( event.type=="keyup" || event.type=="keydown" || event.type=="keypress" ) {
1208                var e=wnd.document.createEvent( "KeyboardEvents" ); // forget it. Apparently it's not supported neither by mozilla nor by opera.
1209                e.initKeyboardEvent(
1210                                event["type"],
1211                                event["cancelable"],
1212                                event["bubbles"],
1213                                wnd.document.defaultView,
1214                                event["which"],
1215                                event["which"],
1216                                event["ctrlKey"],
1217                                event["altKey"],
1218                                event["shiftKey"],
1219                                event["metaKey"],
1220                                false
1221                );
1222                wnd.document.dispatchEvent( e );
1223        }
1224}
1225
1226Test.AnotherWay._print_counter_result=function( url, msg, milliseconds, style )
1227{
1228        return Test.AnotherWay._print_result( url, msg+"<span class=\"counter\">"+(milliseconds/1000).toFixed()+"</span>", style, null );
1229}
1230
1231Test.AnotherWay._g_result_count=0; // for assigning unique ids to result paragraphs
1232
1233// number of pages tested
1234Test.AnotherWay._g_ok_pages=0;
1235Test.AnotherWay._g_fail_pages=0;
1236
1237Test.AnotherWay._print_result=function( url, msg, style, test_objects )
1238{
1239        var results=document.getElementById( "results" );
1240        var r=results.appendChild( document.createElement( "p" ) );
1241        r.id="result"+Test.AnotherWay._g_result_count;
1242        ++Test.AnotherWay._g_result_count;
1243        r.onclick=Test.AnotherWay._toggle_detail;
1244        var text="<span class=\"bullet\">&nbsp;&nbsp;&nbsp;</span>&nbsp;";
1245        if( url!="" ) {
1246                text+=url+":  ";
1247        }
1248        if( msg!=null ) {
1249                text+=msg;
1250        }
1251        if( test_objects!=null ) {
1252                // compose summary and detail texts
1253                var total_ok=0;
1254                var total_detail_ok=0;
1255                var total_fail=0;
1256                var total_detail_fail=0;
1257                var no_plan=0;
1258
1259                var detail=results.appendChild( document.createElement( "div" ) );
1260
1261                if( r.id.match( /^result(\d+)$/ ) ) {
1262                        detail.id="result_detail"+RegExp.$1;
1263                }
1264
1265                for( var i=0; i<test_objects.length; ++i ) {
1266                        var o=test_objects[i];
1267                        var p;
1268                        var p_text;
1269                        p=document.createElement( "P" );
1270                        Test.AnotherWay._set_css_class( p, "result_detail" );
1271                        p_text=o.name;
1272                        if( o.n_fail>0 || o.exception || (o.n_plan!=null && o.n_plan!=o.n_ok+o.n_fail) || (o.n_plan==null && o.n_ok==0 && o.n_fail==0)) {
1273                                ++total_fail;
1274                                p_text+=" <span class=\"fail\">";
1275                                if( o.n_plan!=null && o.n_plan!=o.n_ok+o.n_fail) {
1276                                        p_text+="planned "+o.n_plan+" assertions but got "+(o.n_ok+o.n_fail)+"; ";
1277                                }
1278                                if(o.n_plan==null && o.n_ok==0 && o.n_fail==0) {
1279                                        p_text+="test did not output anything";
1280                                }else {
1281                                        p_text+=" fail "+o.n_fail;
1282                                }
1283                                p_text+="</span>";
1284                        }else {
1285                                ++total_ok;
1286                        }
1287                        p_text+=" ok "+o.n_ok;
1288                        if( o.n_plan==null ) {
1289                                no_plan=1;
1290                                p_text+=" <span class=\"warning\">no plan</span>";
1291                        }
1292                        p.innerHTML=p_text;
1293                        detail.appendChild( p );
1294                        if( o.exception ) {
1295                                p=document.createElement( "P" );
1296                                Test.AnotherWay._set_css_class( p, "result_exception_detail" );
1297                                p.innerHTML="<span class=\"fail\">exception:</span> "+o.exception;
1298                                detail.appendChild( p );
1299                                p=document.createElement( "P" );
1300                                Test.AnotherWay._set_css_class( p, "result_exception_stack_detail" );
1301                                p.innerHTML=o.exception_stack.join( "<br/>" );
1302                                detail.appendChild( p );
1303                        }
1304                        for( var ii=0; ii<o.assertions.length; ++ii ) {
1305                                var oo=o.assertions[ii];
1306                                var status=oo.ok ? "ok" : "<span class=\"fail\">fail</span>";
1307                                p=document.createElement( "P" );
1308                                Test.AnotherWay._set_css_class( p, "result_micro_detail" );
1309                                p.innerHTML=status;
1310                                p.appendChild( document.createTextNode( " "+oo.name ) );
1311                                detail.appendChild( p );
1312                        }
1313                        total_detail_ok+=o.n_ok;
1314                        total_detail_fail+=o.n_fail;
1315                }
1316                if( total_fail || total_detail_fail ) {
1317                        text+=" fail "+total_fail;
1318                }
1319                text+=" ok "+total_ok+" (detailed:";
1320                if( total_fail || total_detail_fail ) {
1321                        text+=" fail "+total_detail_fail;
1322                }
1323                text+=" ok "+total_detail_ok+")";
1324                if( no_plan ) {
1325                        text+=" <span class=\"warning\">no plan</span>";
1326                }
1327                style= total_fail==0 ? "ok" : "fail";
1328                detail.style.display= style=="fail" ? "block" : "none";
1329                detail.style.cursor="text";
1330        }
1331        if( style!=null ) {
1332                Test.AnotherWay._set_css_class( r, style );
1333                if( style=="ok" ) {
1334                        ++Test.AnotherWay._g_ok_pages;
1335                }else if( style=="fail" || style=="badtest" ) {
1336                        ++Test.AnotherWay._g_fail_pages;
1337                }
1338                var pages_total="";
1339                if( Test.AnotherWay._g_fail_pages>0 ) {
1340                        pages_total+=" fail "+Test.AnotherWay._g_fail_pages;
1341                }
1342                pages_total+=" ok "+Test.AnotherWay._g_ok_pages;
1343                Test.AnotherWay._update_results_total( pages_total );
1344        }
1345        r.innerHTML=text;
1346        if( results.scrollHeight!=null && results.scrollTop!=null && results.offsetHeight!=null ) {
1347                results.scrollTop=results.scrollHeight-results.offsetHeight;
1348        }
1349        // when test_objects is not null, the results are final - good time to clean up
1350        if( test_objects!=null ) {
1351                for( var i=0; i<test_objects.length; ++i ) {
1352                        var actions=test_objects[i].delay_actions;
1353                        for( var action_i=0; action_i<actions.length; ++action_i ) {
1354                                var action=actions[action_i];
1355                                if( action.action_kind=="window" && action.wnd_wnd!=null && !action.wnd_no_close ) {
1356                                        action.wnd_wnd.close();
1357                                        action.wnd_wnd=null;
1358                                }
1359                        }
1360                }
1361        }
1362        return r;
1363}
1364Test.AnotherWay._unprint_result=function( child )
1365{
1366        var results=document.getElementById( "results" );
1367        results.removeChild( child );
1368}
1369Test.AnotherWay._toggle_detail=function()
1370{
1371        if( this.id.match( /^result(\d+)$/ ) ) {
1372                var detail=document.getElementById( "result_detail"+RegExp.$1 );
1373                if( detail!=null ) {
1374                        if( detail.style.display=="none" ) {
1375                                detail.style.display="block";
1376                        }else if( detail.style.display=="block" ) {
1377                                detail.style.display="none";
1378                        }
1379                }
1380        }
1381}
1382Test.AnotherWay._update_msg_counter=function( msg, text )
1383{
1384        for( var i=0; i<msg.childNodes.length; ++i ) {
1385                var item=msg.childNodes[i];
1386                if( item.nodeName=="SPAN" && Test.AnotherWay._get_css_class( item )=="counter" ) {
1387                        item.innerHTML=text;
1388                }
1389        }
1390}
1391Test.AnotherWay._update_results_total=function( msg )
1392{
1393        var total=document.getElementById( "total" );
1394        if( total ) {
1395                total.innerHTML=msg;
1396        }
1397}
1398Test.AnotherWay._results_clear_onclick=function()
1399{
1400        var results=document.getElementById( "results" );
1401        results.innerHTML="";
1402        Test.AnotherWay._update_results_total( "" );
1403        Test.AnotherWay._g_ok_pages=0;
1404        Test.AnotherWay._g_fail_pages=0;
1405        var debug=document.getElementById( "debug" );
1406        debug.innerHTML="";
1407}
1408
1409Test.AnotherWay._get_css_class=function( o )
1410{
1411        var c=o.getAttribute( "className" );
1412        if( c==null || c=="" ) {
1413                c=o.getAttribute( "class" );
1414        }
1415        return c;
1416}
1417Test.AnotherWay._set_css_class=function( o, css_class )
1418{
1419        o.setAttribute( "className", css_class );
1420        o.setAttribute( "class", css_class );
1421}
1422
1423Test.AnotherWay._tab_onclick=function()
1424{
1425        var tab=this;
1426        var tabs=[ document.getElementById( "debug_tab" ), document.getElementById( "results_tab" ) ];
1427        var panes=[ document.getElementById( "debug" ), document.getElementById( "results" ) ];
1428        for( var i=0; i<tabs.length; ++i ) {
1429                if( tab==tabs[i] ) {
1430                        Test.AnotherWay._set_css_class( tabs[i], "active_tab" );
1431                        panes[i].style.display="block";
1432                }else {
1433                        Test.AnotherWay._set_css_class( tabs[i], "inactive_tab" );
1434                        panes[i].style.display="none";
1435                }
1436        }
1437}
1438Test.AnotherWay._tab_mouseover=function()
1439{
1440        if( Test.AnotherWay._get_css_class( this )=="inactive_tab" ) {
1441                Test.AnotherWay._set_css_class( this, "inactive_mouseover_tab" );
1442        }
1443}
1444Test.AnotherWay._tab_mouseout=function()
1445{
1446        if( Test.AnotherWay._get_css_class( this )=="inactive_mouseover_tab" ) {
1447                Test.AnotherWay._set_css_class( this, "inactive_tab" );
1448        }
1449}
1450
1451// recording mouse input
1452Test.AnotherWay._record_check_onfocus=function()
1453{
1454        var o=this;
1455        var check_select=o.type!="text";
1456        var div=document.getElementById( "record_div" );
1457        var inputs=div.getElementsByTagName( "input" );
1458        for( var i=0; i<inputs.length; ++i ) {
1459                var input=inputs[i];
1460                if( input.type=="radio" ) {
1461                        if( input.value=="select" ) {
1462                                input.checked=check_select;
1463                        }else if( input.value=="input" ) {
1464                                input.checked=!check_select;
1465                        }
1466                }
1467        }
1468}
1469
1470Test.AnotherWay._g_no_record_msg=null; // not null - recording is unavailable
1471Test.AnotherWay._g_record_timeout_cnt=0; // opening window for a page for recording
1472Test.AnotherWay._g_record_url=null;
1473Test.AnotherWay._g_record_wnd=null;
1474Test.AnotherWay._g_record_random_id=null; // added to element ids of record_control div so that they do not clash with ids already in the page for which input is recorded
1475Test.AnotherWay._g_record_keydown=null; // recording control - which key is down
1476Test.AnotherWay._g_record_ctrl_keydown=false;
1477Test.AnotherWay._g_record_shift_keydown=false;
1478Test.AnotherWay._g_record_control_visible=true; // recording control ui state
1479Test.AnotherWay._g_record_started;
1480Test.AnotherWay._g_record_paused;
1481Test.AnotherWay._g_record_include_mousemove=false;
1482Test.AnotherWay._g_record_start_time; // for time references
1483Test.AnotherWay._g_record_pause_start_time;
1484Test.AnotherWay._g_record_update_time_interval; // showing time in the control ui
1485Test.AnotherWay._g_record_waiting_for_results=false; // waiting for results window to open
1486Test.AnotherWay._g_record_events; // recorded events
1487Test.AnotherWay._g_record_under_cursor; // track element under cursor
1488Test.AnotherWay._g_record_checkpoint_count; // for checkpoint numbering
1489Test.AnotherWay._g_record_mouse_over_record_control; // for avoiding record control highlight on mouseover
1490Test.AnotherWay._g_record_highlighted_element={ element: null, x: null, y: null };
1491
1492Test.AnotherWay._record_control_get_element=function( id )
1493{
1494        if( Test.AnotherWay._g_record_wnd!=null && Test.AnotherWay._g_record_wnd.document!=null ) {
1495                return Test.AnotherWay._g_record_wnd.document.getElementById( id+Test.AnotherWay._g_record_random_id );
1496        }else {
1497                return null;
1498        }
1499}
1500Test.AnotherWay._record_start_onclick=function() // "record" button on the run_tests.html: open a window for a page for which input is recorded
1501{
1502        if( Test.AnotherWay._g_no_record_msg!=null ) {
1503                alert( Test.AnotherWay._g_no_record_msg );
1504                return;
1505        }
1506        if( Test.AnotherWay._g_record_timeout_cnt>0
1507            || (Test.AnotherWay._g_record_wnd!=null && (Test.AnotherWay._g_record_wnd.closed!=null && !Test.AnotherWay._g_record_wnd.closed)) ) { // in opera, closed is null.
1508                alert( "there is already window opened for recording input for a page "+Test.AnotherWay._g_record_url );
1509                return;
1510        }
1511        var div=document.getElementById( "record_div" );
1512        var inputs=div.getElementsByTagName( "input" );
1513        var url=null;
1514        for( var i=0; i<inputs.length; ++i ) {
1515                var input=inputs[i];
1516                if( input.type=="radio" ) {
1517                        if( input.value=="select" && input.checked ) {
1518                                var index=document.getElementById( "record_select" ).selectedIndex;
1519                                if( index>0 ) {
1520                                        url=Test.AnotherWay._g_test_page_urls[index-1].url;
1521                                }
1522                        }else if( input.value=="input" && input.checked ) {
1523                                url=document.getElementById( "record_input" ).value;
1524                        }
1525                }
1526        }
1527        if( url!=null ) {
1528                Test.AnotherWay._g_record_url=url;
1529                Test.AnotherWay._g_record_wnd=window.open( url, "_blank" );
1530                if( Test.AnotherWay._g_record_wnd==null ) {
1531                        alert( "unable to open new window for a page: "+url );
1532                }else {
1533                        Test.AnotherWay._g_record_timeout_cnt=50;
1534                        setTimeout( Test.AnotherWay._record_window_timeout, 100 );
1535                }
1536        }
1537}
1538Test.AnotherWay._record_window_timeout=function()
1539{
1540        if( Test.AnotherWay._is_url_loaded( Test.AnotherWay._g_record_url, Test.AnotherWay._g_record_wnd ) ) {
1541                Test.AnotherWay._record_window_setup( Test.AnotherWay._g_record_wnd );
1542        }else {
1543                if( --Test.AnotherWay._g_record_timeout_cnt>0 ) {
1544                        setTimeout( Test.AnotherWay._record_window_timeout, 100 );
1545                }else {
1546                        alert( "timeout expired while opening new window for a page: "+Test.AnotherWay._g_record_url );
1547                        Test.AnotherWay._g_record_wnd=null;
1548                        Test.AnotherWay._g_record_url=null;
1549                        Test.AnotherWay._g_record_timeout_cnt=0;
1550                }
1551        }
1552}
1553Test.AnotherWay._record_control_randomize_id=function( e, r )
1554{
1555        if( e.id!="" ) {
1556                e.id=e.id+r;
1557        }
1558        for( var c=e.firstChild; c!=null; c=c.nextSibling ) {
1559                Test.AnotherWay._record_control_randomize_id( c, r );
1560        }
1561}
1562Test.AnotherWay._record_window_setup=function( wnd ) // insert recording control into the page for which input is recorded
1563{
1564        Test.AnotherWay._g_record_timeout_cnt=0;
1565        var this_div=document.getElementById( "record_control" );
1566        var record_control=wnd.document.importNode( this_div, true );
1567        Test.AnotherWay._g_record_random_id=(1000*Math.random()).toFixed();
1568        Test.AnotherWay._record_control_randomize_id( record_control, Test.AnotherWay._g_record_random_id );
1569        Test.AnotherWay._g_record_control_visible=true;
1570        Test.AnotherWay._g_record_started=false;
1571        Test.AnotherWay._g_record_paused=false;
1572        Test.AnotherWay._g_record_checkpoint_count=0;
1573        Test.AnotherWay._g_record_mouse_over_record_control=false;
1574        var doc=wnd.document;
1575        doc.body.appendChild( record_control );
1576        // opera sans-serif font is different
1577        if( window.opera ) {
1578                cursor_over_indicator=Test.AnotherWay._record_control_get_element( "record_cursor_over" );
1579                cursor_over_indicator.style.width="18em";
1580                cursor_over_indicator.style.height="2em";
1581                cursor_over_indicator.style.fontSize="7pt";
1582        }
1583        doc.addEventListener( "keydown", Test.AnotherWay._record_control_keydown, true );
1584        doc.addEventListener( "keyup", Test.AnotherWay._record_control_keyup, true );
1585//      doc.addEventListener( "keypress", Test.AnotherWay._record_event, true ); // replaying is not supported by any known browser
1586
1587        doc.body.addEventListener( "mousemove", Test.AnotherWay._record_on_mousemove, true );
1588        doc.body.addEventListener( "click", Test.AnotherWay._record_event, true );
1589        doc.body.addEventListener( "mouseover", Test.AnotherWay._record_event, true );
1590        doc.body.addEventListener( "mouseout", Test.AnotherWay._record_event, true );
1591        doc.body.addEventListener( "mousedown", Test.AnotherWay._record_event, true );
1592        doc.body.addEventListener( "mouseup", Test.AnotherWay._record_event, true );
1593}
1594Test.AnotherWay._record_control_key_disabled=function( k )
1595{
1596        if( k=="c" ) {
1597                return !Test.AnotherWay._g_record_started;
1598        }else if( k=="p" ) {
1599                return !Test.AnotherWay._g_record_started;
1600        }else if( k=="s" ) {
1601                return Test.AnotherWay._g_record_waiting_for_results;
1602        }else {
1603                return false;
1604        }
1605}
1606
1607Test.AnotherWay._record_control_update_ui=function()
1608{
1609        var keydown_color="#fff";
1610        var disabled_color="#aaa";
1611        var button_color="#adf";
1612        var active_color="#fdf";
1613
1614        var display={};
1615        display[false]="none";
1616        display[true]="inline";
1617
1618        var s_button=Test.AnotherWay._record_control_get_element( "record_s" );
1619        var record_on=Test.AnotherWay._record_control_get_element( "record_on" );
1620        var record_off=Test.AnotherWay._record_control_get_element( "record_off" );
1621
1622        s_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( "s" ) ? disabled_color
1623                : Test.AnotherWay._g_record_keydown=="s" ? keydown_color : Test.AnotherWay._g_record_started ? active_color : button_color;
1624        record_on.style.display=display[!Test.AnotherWay._g_record_started];
1625        record_off.style.display=display[Test.AnotherWay._g_record_started];
1626
1627        var h_button=Test.AnotherWay._record_control_get_element( "record_h" );
1628        h_button.style.backgroundColor= Test.AnotherWay._g_record_keydown=="h" ? keydown_color : button_color;
1629
1630        var p_button=Test.AnotherWay._record_control_get_element( "record_p" );
1631        var record_pause_on=Test.AnotherWay._record_control_get_element( "record_pause_on" );
1632        var record_pause_off=Test.AnotherWay._record_control_get_element( "record_pause_off" );
1633        p_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( "p" ) ? disabled_color
1634                : Test.AnotherWay._g_record_keydown=="p" ? keydown_color : Test.AnotherWay._g_record_paused ? active_color : button_color;
1635        record_pause_on.style.display=display[!Test.AnotherWay._g_record_paused];
1636        record_pause_off.style.display=display[Test.AnotherWay._g_record_paused];
1637
1638        var m_button=Test.AnotherWay._record_control_get_element( "record_m" );
1639        var record_include_mousemove=Test.AnotherWay._record_control_get_element( "record_include_mousemove" );
1640        var record_omit_mousemove=Test.AnotherWay._record_control_get_element( "record_omit_mousemove" );
1641        m_button.style.backgroundColor= Test.AnotherWay._g_record_keydown=="m" ? keydown_color : Test.AnotherWay._g_record_include_mousemove ? active_color : button_color;
1642        record_include_mousemove.style.display=display[!Test.AnotherWay._g_record_include_mousemove];
1643        record_omit_mousemove.style.display=display[Test.AnotherWay._g_record_include_mousemove];
1644
1645        var c_button=Test.AnotherWay._record_control_get_element( "record_c" );
1646        c_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( "c" ) ? disabled_color
1647                : Test.AnotherWay._g_record_keydown=="c" ? keydown_color : button_color;
1648
1649        var record_indicator=Test.AnotherWay._record_control_get_element( "record_indicator" );
1650        record_indicator.style.display=display[Test.AnotherWay._g_record_started];
1651
1652        var pause_indicator=Test.AnotherWay._record_control_get_element( "record_pause_indicator" );
1653        pause_indicator.style.display=display[Test.AnotherWay._g_record_paused];
1654
1655        var record_control=Test.AnotherWay._record_control_get_element( "record_control" );
1656        record_control.style.display= Test.AnotherWay._g_record_control_visible ? "block" : "none";
1657
1658        var shift_button=Test.AnotherWay._record_control_get_element( "record_shift_key" );
1659        shift_button.style.backgroundColor= Test.AnotherWay._g_record_shift_keydown ? keydown_color : button_color;
1660
1661        var ctrl_button=Test.AnotherWay._record_control_get_element( "record_ctrl_key" );
1662        ctrl_button.style.backgroundColor= Test.AnotherWay._g_record_ctrl_keydown ? keydown_color : button_color;
1663}
1664Test.AnotherWay._record_format_time=function( t )
1665{
1666        t=new Date( t );
1667        var m=t.getMinutes();
1668        var s=t.getSeconds();
1669        var str= m==0 ? "" : m+"m ";
1670        str+=s+"s.";
1671        return str;
1672}
1673Test.AnotherWay._record_control_update_time=function()
1674{
1675        var time_display=Test.AnotherWay._record_control_get_element( "record_time" );
1676        if( time_display!=null ) {
1677                time_display.innerHTML=Test.AnotherWay._record_format_time( (new Date()).getTime()-Test.AnotherWay._g_record_start_time );
1678        }
1679}
1680Test.AnotherWay._record_control_update_highlight=function( elem, style, event )
1681{
1682        if( elem==null ) {
1683                Test.AnotherWay._record_highlight_border( null );
1684        }else {
1685                var pos=Test.AnotherWay._get_page_coords( elem );
1686                if( style=="ball" || elem!=Test.AnotherWay._g_record_highlighted_element.element || pos.x!=Test.AnotherWay._g_record_highlighted_element.x || pos.y!=Test.AnotherWay._g_record_highlighted_element.y ) {
1687                        Test.AnotherWay._g_record_highlighted_element={ element: elem, x: pos.x, y: pos.y };
1688                        Test.AnotherWay._record_highlight_border( elem, style, event );
1689                }
1690        }
1691}
1692Test.AnotherWay._record_decode_key=function( event )
1693{
1694        var k=null;
1695        if( event==null ) {
1696                k=Test.AnotherWay._g_record_wnd.event.keyCode;
1697        }else {
1698                k=event.which;
1699        }
1700        if( k==83 ) {
1701                return "s";
1702        }else if( k==72 ) {
1703                return "h";
1704        }else if( k==73 ) {
1705                return "i";
1706        }else if( k==80 ) {
1707                return "p";
1708        }else if( k==67 ) {
1709                return "c";
1710        }else if( k==77 ) {
1711                return "m";
1712        }else if( k==16 ) {
1713                return "shift";
1714        }else if( k==17 ) {
1715                return "ctrl";
1716        }else if( k==18 ) {
1717                return "alt";
1718        }else if( k==19 ) {
1719                return "pause";
1720        }else if( k==123 ) {
1721                return "f12";
1722        }
1723        return "";
1724}
1725Test.AnotherWay._record_control_keydown=function( event )
1726{
1727        var handled=false;
1728        var k=Test.AnotherWay._record_decode_key( event );
1729        if( k=="shift" ) {
1730                Test.AnotherWay._g_record_shift_keydown=true;
1731        }else if( k=="ctrl" ) {
1732                Test.AnotherWay._g_record_ctrl_keydown=true;
1733        }else if( k!="" && (Test.AnotherWay._g_record_keydown==null || Test.AnotherWay._g_record_keydown==k) ) {
1734                if( Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown && !Test.AnotherWay._record_control_key_disabled( k ) ) {
1735                        Test.AnotherWay._g_record_keydown=k;
1736                        handled=true;
1737                }
1738        }else {
1739                Test.AnotherWay._g_record_keydown="";
1740        }
1741        Test.AnotherWay._record_control_update_ui();
1742        if( !handled ) {
1743//              Test.AnotherWay._record_event( event ); // replaying is not supported in any known browser
1744        }
1745        return;
1746}
1747Test.AnotherWay._record_control_keyup=function( event )
1748{
1749        var handled=false;
1750        var k=Test.AnotherWay._record_decode_key( event );
1751        if( k=="shift" ) {
1752                Test.AnotherWay._g_record_shift_keydown=false;
1753        }else if( k=="ctrl" ) {
1754                Test.AnotherWay._g_record_ctrl_keydown=false;
1755        }else if( k!="" && k==Test.AnotherWay._g_record_keydown && Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown  ) {
1756                if( k=="s" ) {
1757                        Test.AnotherWay._g_record_started=!Test.AnotherWay._g_record_started;
1758                        if( Test.AnotherWay._g_record_started ) {
1759                                Test.AnotherWay._g_record_events=[];
1760                                Test.AnotherWay._g_record_start_time=(new Date()).getTime();
1761                                Test.AnotherWay._record_control_update_time();
1762                                Test.AnotherWay._g_record_update_time_interval=window.setInterval( Test.AnotherWay._record_control_update_time, 200 );
1763                        }else {
1764                                Test.AnotherWay._record_control_update_highlight( null );
1765                                if( !Test.AnotherWay._g_record_paused ) {
1766                                        window.clearInterval( Test.AnotherWay._g_record_update_time_interval );
1767                                }
1768                                Test.AnotherWay._g_record_waiting_for_results=true;
1769                                // open a new window for self, pass a parameter to dump recorded events as javascript code there
1770                                // (the easiest way to obtain a document from the same origin, so it's writable, is to open this same page again)
1771                                Test.AnotherWay._g_record_paused=false;
1772                                var loc=window.location;
1773                                loc=loc.protocol+"//"+loc.host+loc.pathname+"?recording_results="+Test.AnotherWay._g_record_random_id;
1774                                if( window.open( loc, "_blank" )==null ) {
1775                                        alert( "unable to open new window for results" );
1776                                }
1777                        }
1778                        handled=true;
1779                }else if( k=="h" ) {
1780                        Test.AnotherWay._g_record_control_visible=!Test.AnotherWay._g_record_control_visible;
1781                        handled=true;
1782                }else if( k=="p" ) {
1783                        Test.AnotherWay._g_record_paused=!Test.AnotherWay._g_record_paused;
1784                        if( Test.AnotherWay._g_record_paused ) {
1785                                Test.AnotherWay._g_record_pause_start_time=(new Date()).getTime();
1786                                if( Test.AnotherWay._g_record_started ) {
1787                                        window.clearInterval( Test.AnotherWay._g_record_update_time_interval );
1788                                }
1789                                Test.AnotherWay._record_control_update_highlight( null );
1790                        }else {
1791                                var pause_duration=(new Date()).getTime()-Test.AnotherWay._g_record_pause_start_time;
1792                                Test.AnotherWay._g_record_start_time+=pause_duration;
1793                                Test.AnotherWay._g_record_update_time_interval=window.setInterval( Test.AnotherWay._record_control_update_time, 200 );
1794                        }
1795                        handled=true;
1796                }else if( k=="m" ) {
1797                        Test.AnotherWay._g_record_include_mousemove=!Test.AnotherWay._g_record_include_mousemove;
1798                        handled=true;
1799                }else if( k=="c" ) {
1800                        var o=Test.AnotherWay._record_checkpoint();
1801                        Test.AnotherWay._record_display_checkpoint( o );
1802                        Test.AnotherWay._record_flash_border( "#24d" );
1803                        handled=true;
1804                }
1805        }
1806        Test.AnotherWay._g_record_keydown=null;
1807        Test.AnotherWay._record_control_update_ui();
1808        if( !handled ) {
1809//              Test.AnotherWay._record_event( event ); // replaying is not supported in any known browser
1810        }
1811        return;
1812}
1813Test.AnotherWay._record_html_node_path=function( node )
1814{
1815        if( node==null ) {
1816                return null;
1817        }
1818        var path=[];
1819        while( true ) {
1820                if( node.id!=null && node.id!="" ) {
1821                        path.unshift( "#"+node.id+" "+node.nodeName );
1822                        break;
1823                }else {
1824                        var parent_node=node.parentNode;
1825                        if( parent_node==null ) {
1826                                return []; // no BODY up the path - this node is screwed (browsers differ in what's above the body), discard
1827                        }else {
1828                                var i=0;
1829                                var found=false;
1830                                for( var child=parent_node.firstChild; child!=null; child=child.nextSibling ) {
1831                                        if( child==node ) {
1832                                                found=true;
1833                                                break;
1834                                        }
1835                                        if( child.nodeType==1 ) { // count only HTML element nodes
1836                                                ++i;
1837                                        }
1838                                }
1839                                if( !found ) {
1840                                        i=-1;
1841                                }
1842                                path.unshift( i+" "+node.nodeName );
1843                                if( parent_node.nodeName=="BODY" || parent_node.nodeName=="body" ) {
1844                                        break;
1845                                }
1846                                node=parent_node;
1847                        }
1848                }
1849        }
1850        return path;
1851}
1852Test.AnotherWay._record_node_path_to_string=function( path )
1853{
1854        var s="";
1855        if( path!=null ) {
1856                for( var i=0; i<path.length; ++i ) {
1857                        s+= i==0 ? "" : ", ";
1858                        var elem=path[i].split( " " );
1859                        if( elem[0].charAt( 0 )=="#" ) {
1860                                s+=elem[1]+" "+elem[0];
1861                        }else {
1862                                s+=elem[1]+" ["+elem[0]+"]";
1863                        }
1864                }
1865        }
1866        return s;
1867}
1868Test.AnotherWay._record_node_path_to_node=function( path_str, doc )
1869{
1870        if( path_str==null ) {
1871                return null;
1872        }
1873        var path=path_str.split( "," );
1874        var node=doc.body;
1875        for( var i=0; i<path.length; ++i ) {
1876                var node_i=path[i].split( " " )[0];
1877                if( node_i.charAt( 0 )=="#" ) {
1878                        node=doc.getElementById( node_i.substring( 1 ) );
1879                }else {
1880                        if( node_i<0 || node_i>=node.childNodes.length ) {
1881                                node=null;
1882                        }else {
1883                                node=node.firstChild;
1884                                while( node!=null ) {
1885                                        if( node.nodeType==1 ) {  // count only HTML element nodes
1886                                                if( node_i==0 ) {
1887                                                        break;
1888                                                }
1889                                                --node_i;
1890                                        }
1891                                        node=node.nextSibling;
1892                                }
1893                        }
1894                }
1895                if( node==null ) {
1896                        return null;
1897                }
1898        }
1899        return node;
1900}
1901Test.AnotherWay._record_control_contains_id=function( s )
1902{
1903        return s.match( /^#record_[\w_]+/ ) && s.match( Test.AnotherWay._g_record_random_id );
1904}
1905Test.AnotherWay._record_checkpoint=function()
1906{
1907        var o={ type: "_checkpoint", time: (new Date()).getTime()-Test.AnotherWay._g_record_start_time, which: Test.AnotherWay._g_record_checkpoint_count++,
1908                        target: Test.AnotherWay._record_html_node_path( Test.AnotherWay._g_record_under_cursor ) };
1909        Test.AnotherWay._g_record_events.push( o );
1910        return o;
1911}
1912Test.AnotherWay._record_event=function( event )
1913{
1914        var unneeded=["rangeOffset","eventPhase","timeStamp","isTrusted","popupWindowFeatures","rangeOffset"];
1915        if( Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused ) {
1916                var o={};
1917                for( var n in event ) {
1918                        var needed=!n.match( /^[A-Z0-9_]+$/ );
1919                        if( needed ) {
1920                                for( var ui=0; ui<unneeded.length; ++ui ) {
1921                                        if( unneeded[ui]==n ) {
1922                                                needed=false;
1923                                                break;
1924                                        }
1925                                }
1926                                if( needed ) {
1927                                        var value=event[n];
1928                                        if( typeof( value )!="object" && typeof( value )!="function" ) {
1929                                                o[n]=value;
1930                                        }else if( n=="target" || n=="relatedTarget" ) {
1931                                                o[n]=Test.AnotherWay._record_html_node_path( value );
1932                                        }
1933                                }
1934                        }
1935                }
1936                o["time"]=(new Date()).getTime()-Test.AnotherWay._g_record_start_time;
1937                var over_record_control= o["target"]!=null && o["target"][0]!=null && Test.AnotherWay._record_control_contains_id( o["target"][0] );
1938                if( !over_record_control ) {
1939                        Test.AnotherWay._g_record_events.push( o );
1940                }
1941        }
1942        return true;
1943}
1944Test.AnotherWay._record_on_mousemove=function( event )
1945{
1946        var path=Test.AnotherWay._record_html_node_path( event.target );
1947        var new_mouse_over_record_control= path!=null && path[0]!=null && Test.AnotherWay._record_control_contains_id( path[0] );
1948        if( new_mouse_over_record_control!=Test.AnotherWay._g_record_mouse_over_record_control ) {
1949                Test.AnotherWay._g_record_mouse_over_record_control=new_mouse_over_record_control;
1950                Test.AnotherWay._record_control_update_ui();
1951        }
1952        if( event.target!=null && event.target!=Test.AnotherWay._g_record_under_cursor ) {
1953                Test.AnotherWay._g_record_under_cursor=event.target;
1954                var s="";
1955                if( path==null || path[0]==null || !Test.AnotherWay._record_control_contains_id( path[0] ) ) {
1956                        s=Test.AnotherWay._record_node_path_to_string( path );
1957                }
1958                if( s=="" ) {
1959                        s="&nbsp;";
1960                }
1961                var cursor_over_indicator=Test.AnotherWay._record_control_get_element( "record_cursor_over" );
1962                cursor_over_indicator.innerHTML=s;
1963        }
1964
1965        var highlight_element=null;
1966        if( !Test.AnotherWay._g_record_mouse_over_record_control && Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused ) {
1967                highlight_element=event.target;
1968        }
1969        // highlight border disabled on recording - it causes page to scroll, issuing spurious mouseover/mouseout event
1970        //Test.AnotherWay._record_control_update_highlight( highlight_element, "border" );
1971
1972        if( Test.AnotherWay._g_record_include_mousemove ) {
1973                Test.AnotherWay._record_event( event );
1974        }
1975        return true;
1976}
1977Test.AnotherWay._record_display_checkpoint=function( o )
1978{
1979        var checkpoints_div=Test.AnotherWay._record_control_get_element( "record_checkpoints" );
1980        var p=checkpoints_div.appendChild( checkpoints_div.ownerDocument.createElement( "div" ) );
1981        p.style.marginTop="3px";
1982        p.style.font="normal normal 8pt sans-serif";
1983        p.style.color="#000";
1984        p.style.textAligh="left";
1985        p.style.position="relative";
1986        p.style.width="100%";
1987        var checkpoint_text="";
1988        checkpoint_text+="#"+(o.which+1);
1989        checkpoint_text+="  "+Test.AnotherWay._record_format_time( o.time );
1990        if( o.target!=null ) {
1991                checkpoint_text+=Test.AnotherWay._record_node_path_to_string( o.target );
1992        }
1993        p.appendChild( p.ownerDocument.createTextNode( checkpoint_text ) );
1994}
1995Test.AnotherWay._record_save_results=function( doc )
1996{
1997        // strange, but DOM-style append does not work here in opera 8.
1998        var append=function( s ) { doc.write( "<div>"+s+"</div>" ); };
1999        append( "/* paste this data into your javascript and pass it as an argument to replay_events method */" );
2000        append( "{ checkpoints: [" );
2001        var first_checkpoint=true;
2002        for( var i=0; i<Test.AnotherWay._g_record_events.length; ++i ) {
2003                var o=Test.AnotherWay._g_record_events[i];
2004                if( o.type=="_checkpoint" ) {
2005                        var str= first_checkpoint ? "" : "}, ";
2006                        str+="function( tst, wnd ) { // #"+o.which+" time "+Test.AnotherWay._record_format_time( o.time )+" cursor was over "+Test.AnotherWay._record_node_path_to_string( o.target );
2007                        append( str );
2008                        first_checkpoint=false;
2009                }
2010        }
2011        if( !first_checkpoint ) {
2012                append( "}" );
2013        }
2014        append( "], events: [ " );
2015        var prev_time=0;
2016        for( var i=0; i<Test.AnotherWay._g_record_events.length; ++i ) {
2017                var o=Test.AnotherWay._g_record_events[i];
2018                var s="";
2019                s+= "{";
2020                var n_first=true;
2021                for( var n in o ) {
2022                        if( n=="time" ) { // convert to relative time
2023                                var cur_time=o[n]-0;
2024                                o[n]=cur_time-prev_time;
2025                                prev_time=cur_time;
2026                        }
2027                        s+=n_first ? n : ", "+n;
2028                        s+=":";
2029                        if( o[n]==null ) {
2030                                s+="null";
2031                        }else {
2032                                s+="\""+o[n]+"\"";
2033                        }
2034                        n_first=false;
2035                }
2036                s+= i==Test.AnotherWay._g_record_events.length-1 ? "}" : "},";
2037                append( s );
2038        }
2039        append( "] }" );
2040        append( ";" );
2041}
2042
2043Test.AnotherWay._g_record_border; // border highlighting element under cursor
2044Test.AnotherWay._g_record_border_flashes=[]; // array of { color: color, timeout: milliseconds }
2045Test.AnotherWay._g_record_border_flashing=false;
2046Test.AnotherWay._g_record_border_normal_color="#d4b";
2047Test.AnotherWay._record_flash_border_timeout=function()
2048{
2049        var color=Test.AnotherWay._g_record_border_normal_color;
2050        var timeout=null;
2051        if( Test.AnotherWay._g_record_border_flashes.length!=0 ) {
2052                color=Test.AnotherWay._g_record_border_flashes[0].color;
2053                timeout=Test.AnotherWay._g_record_border_flashes[0].timeout;
2054                Test.AnotherWay._g_record_border_flashes.splice( 0, 1 );
2055        }
2056        if( Test.AnotherWay._g_record_border!=null ) {
2057                for( var i=0; i<Test.AnotherWay._g_record_border.length; ++i ) {
2058                        Test.AnotherWay._g_record_border[i].style.backgroundColor=color;
2059                }
2060        }
2061        if( timeout!=null ) {
2062                setTimeout( Test.AnotherWay._record_flash_border_timeout, timeout );
2063        }else {
2064                Test.AnotherWay._g_record_border_flashing=false;
2065        }
2066}
2067Test.AnotherWay._get_page_coords=function( elm )
2068{
2069        var point = { x: 0, y: 0 };
2070        while( elm )  {
2071                point.x+=elm.offsetLeft;
2072                point.y+=elm.offsetTop;
2073                elm=elm.offsetParent;
2074         }
2075        return point;
2076}
2077Test.AnotherWay._set_page_coords=function( elm, x, y )
2078{
2079        var parent_coords={ x: 0, y: 0 };
2080        if( elm.offsetParent )  {
2081                parent_coords=Test.AnotherWay._get_page_coords( elm.offsetParent );
2082        }
2083        var new_x=x-parent_coords.x;
2084        if( new_x<0 ) {
2085                new_x=0;
2086        }
2087        elm.style.left=new_x+'px';
2088        var new_y=y-parent_coords.y;
2089        if( new_y<0 ) {
2090                new_y=0;
2091        }
2092        elm.style.top=new_y+'px';
2093}
2094Test.AnotherWay._record_setup_highlight_positions=function( element, style, coords, positions )
2095{
2096        if( style=="border" ) {
2097                var width=element.clientWidth;
2098                var height=element.clientHeight;
2099                var step=0;
2100                var thickness=2;
2101                var fudge_expand=4;
2102                positions.push( { x: coords.x-step-thickness, y: coords.y-step-thickness, width: width+2*step+2*thickness+fudge_expand, height: thickness } );
2103                positions.push( { x: coords.x+width+step+fudge_expand, y: coords.y-step-thickness, width: thickness, height: height+2*step+2*thickness+fudge_expand } );
2104                positions.push( { x:positions[0].x, y:positions[0].y, width:positions[0].width, height:positions[0].height } );
2105                positions.push( { x:positions[1].x, y:positions[1].y, width:positions[1].width, height:positions[1].height } );
2106                positions[2].y+=height+thickness+2*step+fudge_expand;
2107                positions[3].x-=width+thickness+2*step+fudge_expand;
2108        }else if( style=="ball" ) {
2109                positions.push( { x: coords.x+2, y: coords.y, width: 2, height: 6 } );
2110                positions.push( { x: coords.x, y: coords.y+2, width: 6, height: 2 } );
2111                positions.push( { x: coords.x+1, y: coords.y+1, width: 4, height: 4 } );
2112        }
2113}
2114Test.AnotherWay._record_highlight_border=function( element, style, event ) // null - hide border
2115{
2116        if( element!=null ) {
2117                if( Test.AnotherWay._g_record_border==null || Test.AnotherWay._g_record_border[0].ownerDocument!=element.ownerDocument ) {
2118                        Test.AnotherWay._g_record_border=[];
2119                        var n= style=="border" ? 4 : style=="ball" ? 3 : 0;
2120                        for( var i=0; i<4; ++i ) {
2121                                var b=element.ownerDocument.createElement( "div" );
2122                                b.style.position="absolute";
2123                                b.style.zIndex="1";
2124                                b.style.backgroundColor=Test.AnotherWay._g_record_border_normal_color;
2125                                element.ownerDocument.body.appendChild( b );
2126                                Test.AnotherWay._g_record_border.push( b );
2127                        }
2128                }
2129                var coords=null;
2130                if( style=="border" ) {
2131                        coords=Test.AnotherWay._get_page_coords( element );
2132                }else if( style=="ball" ) {
2133                        if( event!=null ) {
2134                                if( event.pageX!=null && event.pageY!=null ) {
2135                                        coords={ x: event.pageX-0, y: event.pageY-0 };
2136                                }else if( event.clientX!=null && event.clientY!=null ) {
2137                                        var doc=element.ownerDocument;
2138                                        if( doc!=null ) {
2139                                                coords={ x: (event.clientX-0)+doc.body.scrollLeft, y: (event.clientY-0)+doc.body.scrollTop };
2140                                        }
2141                                }
2142                        }
2143                }
2144                if( coords!=null && element.clientWidth!=null && element.clientHeight!=null ) {
2145                        var positions=[];
2146                        Test.AnotherWay._record_setup_highlight_positions( element, style, coords, positions );
2147                        for( var i=0; i<positions.length; ++i ) {
2148                                var b=Test.AnotherWay._g_record_border[i];
2149                                var p=positions[i];
2150                                Test.AnotherWay._set_page_coords( b, p.x, p.y );
2151                                b.style.width=p.width+"px";
2152                                b.style.height=p.height+"px";
2153                                b.style.display="block";
2154                        }
2155                }
2156        }else {
2157                if( Test.AnotherWay._g_record_border!=null ) {
2158                        for( var i=0; i<Test.AnotherWay._g_record_border.length; ++i ) {
2159                                Test.AnotherWay._g_record_border[i].style.display="none";
2160                        }
2161                }
2162        }
2163}
2164Test.AnotherWay._record_flash_border=function( color )
2165{
2166        if( Test.AnotherWay._g_record_border_flashing ) { //already
2167                Test.AnotherWay._g_record_border_flashes.push( { color: Test.AnotherWay._g_record_border_normal_color, timeout:300 } );
2168                Test.AnotherWay._g_record_border_flashes.push( { color: color, timeout:600 } );
2169        }else {
2170                Test.AnotherWay._g_record_border_flashing=true;
2171                Test.AnotherWay._g_record_border_flashes.push( { color: color, timeout:600 } );
2172                Test.AnotherWay._record_flash_border_timeout();
2173        }
2174}
2175Test.AnotherWay._record_prepare_doc_for_results=function()
2176{
2177        document.open();
2178        document.write( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" );
2179        document.write( "<html><head><title> Input recording results</title>" );
2180        document.write( "<style type=\"text/css\">" );
2181        document.write( "body { font: normal normal smaller sans-serif; }" );
2182        document.write( "div { margin-top: 3px; }" );
2183        document.write( "</style></head><body>" );
2184        // opera and mozilla disagree over who the opener is.
2185        if( typeof( window.opener.Test )!="undefined" && typeof( window.opener.Test.AnotherWay )!="undefined" ) {
2186                window.opener.Test.AnotherWay._record_save_results( document );
2187                window.opener.Test.AnotherWay._g_record_waiting_for_results=false;
2188                window.opener.Test.AnotherWay._record_control_update_ui();
2189        }else if( typeof( window.opener.opener.Test  )!="undefined" && typeof( window.opener.opener.Test.AnotherWay )!="undefined" ) {
2190                window.opener.opener.Test.AnotherWay._record_save_results( document );
2191                window.opener.opener.Test.AnotherWay._g_record_waiting_for_results=false;
2192                window.opener.opener.Test.AnotherWay._record_control_update_ui();
2193        }
2194        document.write( "</body>" );
2195        document.close();
2196}
2197
2198// global initialization
2199onload=function()
2200{
2201        if( window.opera ) {
2202                var good_opera=typeof( window.opera.version )=="function";
2203                good_opera=good_opera && window.opera.version().match( /^\s*(\d+)/ );
2204                good_opera=good_opera && RegExp.$1>=8;
2205        }
2206        var span=document.createElement( "SPAN" );
2207        span.innerHTML="<!--[if IE]><br /><![endif]-"+"->";
2208        var is_ie=span.getElementsByTagName( "BR" ).length>0;
2209
2210        Test.AnotherWay._g_test_iframe=window.frames.test_iframe;
2211
2212        var query_str=window.location.search;
2213        if( query_str.charAt( 0 )=="?" ) {
2214                query_str=query_str.substring( 1 );
2215        }
2216        var testlist_page="list-tests.html";
2217        var auto_run=false;
2218        if( query_str!="" ) {
2219                var params=[query_str];
2220                if( query_str.indexOf( ";" )!=-1 ) {
2221                        params=query_str.split( ";" );
2222                }else if( query_str.indexOf( "&" )!=-1 ) {
2223                        params=query_str.split( "&" );
2224                }
2225                for( var param_i=0; param_i<params.length; ++param_i ) {
2226                        var param=params[param_i].split( "=" );
2227                        if( param[0]=="recording_results" ) {
2228                                if( window.opener!=null ) {
2229                                        // we were told to show recording results - replace everything in the document with the results
2230                                        Test.AnotherWay._record_prepare_doc_for_results();
2231                                        return;
2232                                }
2233                        }else if( param[0]=="testpage" ) {
2234                                Test.AnotherWay._add_test_page_url( decodeURIComponent( param[1] ), "anotherway" );
2235                        }else if( param[0]=="jsantestpage" ) {
2236                                Test.AnotherWay._add_test_page_url( decodeURIComponent( param[1] ), "jsan" );
2237                        }else if( param[0]=="testlist" ) {
2238                                testlist_page=decodeURIComponent( param[1] );
2239                        }else if( param[0]=="testframe" ) {
2240                                if( window.opera && !good_opera ) {
2241                                        Test.AnotherWay._show_error( "testframe parameter does not work in versions of Opera prior to 8.0. Sorry (pathches are welcome)." );
2242                                        // Opera 7 barfs on attempt to access frame.frameElement.
2243                                        // if someone knows a way to assign onload handler to that iframe in Opera 7
2244                                        // without disrupting code that works in other browsers, patches are welcome.
2245                                }else {
2246                                        var frame_path=param[1].split( "." );
2247                                        var frame=top;
2248                                        for( var frame_path_i=0; frame_path_i<frame_path.length; ++frame_path_i ) {
2249                                                frame=frame[frame_path[frame_path_i]];
2250                                        }
2251                                        if( frame==null ) {
2252                                                Test.AnotherWay._show_error( "unable to find frame specified for loading test pages: "+param[1] );
2253                                        }else {
2254                                                if( frame.frameElement!=null ) { // for the following assignement to onload to work, frameElement is required
2255                                                        frame=frame.frameElement;
2256                                                }
2257                                                Test.AnotherWay._g_test_iframe=frame;
2258                                        }
2259                                }
2260                        }else if( param[0]=="testframe_no_clear" ) {
2261                                Test.AnotherWay._g_test_frame_no_clear=true;
2262                        }else if( param[0]=="windows" ) {
2263                if (param[1] == "none") {
2264                }
2265                        }else if( param[0]=="run" ) {
2266                                auto_run=true;
2267                                if( param[1]=="all" ) {
2268                                        Test.AnotherWay._g_pages_to_run="all";
2269                                }else {
2270                                        if( Test.AnotherWay._g_pages_to_run==null || Test.AnotherWay._g_pages_to_run=="all" ) {
2271                                                Test.AnotherWay._g_pages_to_run=[];
2272                                        }
2273                                        var pages=param[1].split( "," );
2274                                        for( var i=0; i<pages.length; ++i ) {
2275                                                Test.AnotherWay._g_pages_to_run.push( pages[i] );
2276                                        }
2277                                }
2278                        }
2279                }
2280        }
2281        if( Test.AnotherWay._g_test_page_urls.length==0 ) {  // if no individual pages were given on the command line, load the list
2282                var result=Test.AnotherWay._set_iframe_location( window.frames["list_iframe"], testlist_page );
2283                if( result.msg!=null ) {
2284                        Test.AnotherWay._show_error( result.msg );
2285                }
2286                Test.AnotherWay._g_run_on_list_load=auto_run;
2287        }else {
2288                Test.AnotherWay._g_run_on_main_load=auto_run;
2289        }
2290
2291        var f=Test.AnotherWay._g_test_iframe;
2292        try {
2293                if( f.attachEvent!=null ) {
2294                        f.attachEvent( "onload", Test.AnotherWay._test_page_onload );
2295                }else {
2296                        f.onload=Test.AnotherWay._test_page_onload;
2297                }
2298                if( Test.AnotherWay._g_test_iframe.nodeType!=null && Test.AnotherWay._g_test_iframe.contentWindow!=null ) { // it's iframe element, not the iframe. we need iframe.
2299                        Test.AnotherWay._g_test_iframe=Test.AnotherWay._g_test_iframe.contentWindow;
2300                }
2301        }catch(e) {
2302                // ignore stupid opera error if the frame has onload handler assigned in the inline html
2303        }
2304        var handlers={
2305                "run_all": { "onclick": Test.AnotherWay._run_all_onclick },
2306                "run_selected": { "onclick": Test.AnotherWay._run_selected_onclick },
2307                "unselect_all": { "onclick": Test.AnotherWay._unselect_all_onclick },
2308                "record_select": { "onfocus": Test.AnotherWay._record_check_onfocus },
2309                "record_input": { "onfocus": Test.AnotherWay._record_check_onfocus },
2310                "record_start": { "onclick": Test.AnotherWay._record_start_onclick },
2311                "clear_btn": { "onclick": Test.AnotherWay._results_clear_onclick },
2312                "results_tab": { "onclick": Test.AnotherWay._tab_onclick, "onmouseover": Test.AnotherWay._tab_mouseover, "onmouseout": Test.AnotherWay._tab_mouseout },
2313                "debug_tab": { "onclick": Test.AnotherWay._tab_onclick, "onmouseover": Test.AnotherWay._tab_mouseover, "onmouseout": Test.AnotherWay._tab_mouseout }
2314        };
2315        for( var hs in handlers ) {
2316                var o=document.getElementById( hs );
2317                if( o!=null ) {
2318                        for( var h in handlers[hs] ) {
2319                                o[h]=handlers[hs][h];
2320                        }
2321                }else {
2322                        Test.AnotherWay._show_error( "unable to set "+h+" handler: id "+hs+" not found" );
2323                }
2324        }
2325
2326        if( window.opera && !good_opera ) {
2327                Test.AnotherWay._g_no_record_msg="Input events recording and replaying is not available in opera versions prior to 8.0.";
2328        }
2329        if( is_ie ) {
2330                Test.AnotherWay._g_no_record_msg="Input events recording and replaying is not available in internet explorer.";
2331        }
2332        if( Test.AnotherWay._g_no_record_msg!=null ) {
2333                var no_record_p=document.getElementById( "record_not_supported" );
2334                no_record_p.style.display="block";
2335                no_record_p.appendChild( document.createTextNode( Test.AnotherWay._g_no_record_msg ) );
2336        }
2337
2338        Test.AnotherWay._g_main_loaded=true;
2339        if( Test.AnotherWay._g_run_on_main_load ) {
2340                Test.AnotherWay._g_run_on_main_load=false;
2341                Test.AnotherWay._run_pages_to_run();
2342        }
2343}
2344Test.AnotherWay._test_object_t.prototype.open_window=null;
2345// -->
2346</script>
2347<script type="text/javascript" src="xml_eq.js"></script>
2348<script type="text/javascript" src="geom_eq.js"></script>
2349</head><body>
2350
2351<div id="col1">
2352<div id="col1_header">Test pages:</div>
2353<div id="scroller">
2354<table id="testtable">
2355</table>
2356</div>
2357<div id="run_buttons">
2358<input type="button" value=" clear " id="clear_btn" />
2359<input type="button" value=" run all " id="run_all" />
2360<input type="button" value=" run selected " id="run_selected" />
2361<input type="button" value=" unselect all " id="unselect_all" />
2362</div>
2363<input type="checkbox" id="dont_close_test_windows" /> do not close windows opened by tests
2364<div id="error"></div>
2365<div id="record_div">
2366<p id="record_not_supported" style="display:none"></p>
2367<p>Record mouse input for the page:</p>
2368<p><input type="radio" name="record_choose" value="select" checked="checked" /> <select id="record_select"><option selected="selected">-- select a page: --</option></select></p>
2369<p><input type="radio" name="record_choose" value="input" /> or enter page url: <input type="text" id="record_input" /></p>
2370<p><input type="button" value=" record " id="record_start" /></p>
2371</div>
2372</div>
2373
2374<div id="col2">
2375<div id="right_header">
2376<span id="results_count">Results: <span id="total"></span></span>
2377<span id="results_tab" class="active_tab" style="visibility:hidden">Results</span>
2378<span id="debug_tab" class="inactive_tab" style="visibility:hidden">Debug</span>
2379</div>
2380<div id="right_frame">
2381<div id="results"></div>
2382<div id="debug"></div>
2383</div>
2384</div>
2385
2386<span style="display:none">
2387<iframe name="list_iframe" onload="Test.AnotherWay._list_iframe_onload();"></iframe>
2388<iframe name="test_iframe" onload="Test.AnotherWay._test_page_onload();"></iframe>
2389
2390<!-- record_control div is to be imported into other documents, so all its styles are inline -->
2391-<div id="record_control" style="position:absolute;bottom:0;left:0;margin:0;padding:0.5em;width:22em;height:22em;border:1px solid;background:#ffd;font: normal normal 8pt sans-serif; color:#000; text-align: left">
2392
2393<p style="margin:0 0 0 0; padding:0">
2394&nbsp;
2395<span style="display:none;font-weight:bold;color:#408" id="record_indicator">
2396recording. <span style="font-weight:normal">time: <span id="record_time"></span></span><span id="record_pause_indicator"> paused</span>
2397</span>
2398</p>
2399
2400<div id="record_cursor_over" style="margin:0;padding:2px;width:14em;height:1.1em;overflow:hidden;float:right;border:1px solid #777;background:#fff;font: normal normal 8pt sans-serif;position:relative;top:3px;color:#000;text-align:left;">&nbsp;</div>
2401<p style="margin:2px 0 0 0; padding:0">
2402cursor is over
2403</p>
2404
2405<p style="margin:8px 0 0 0; padding:0;">
2406 keyboard control: press
2407 <span id="record_ctrl_key" style="border:1px solid #226;background:#adf;padding:0 0.5em">ctrl</span> -
2408 <span id="record_shift_key" style="border:1px solid #226;background:#adf;padding:0 0.5em">shift</span> -
2409</p>
2410
2411<p style="margin:4px 0 0 0; padding:0">
2412<span id="record_s" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">s</span>
2413<span id="record_on">to <b>start</b> recording</span>
2414<span id="record_off" style="display:none">to <b>stop</b> recording</span>
2415</p>
2416
2417<p style="margin:4px 0 0 0; padding:0">
2418<span id="record_h" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">h</span>
2419<span>to <b>hide/show</b> this window</span>
2420</p>
2421
2422<p style="margin:4px 0 0 0; padding:0">
2423<span id="record_m" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">m</span>
2424<span id="record_include_mousemove">to <b> record</b> mousemove</span>
2425<span id="record_omit_mousemove" style="display:none">to <b>omit</b> mousemove</span>
2426</p>
2427
2428<p style="margin:4px 0 0 0; padding:0">
2429<span id="record_p" style="border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">p</span>
2430<span id="record_pause_on">to <b> pause</b> recording</span>
2431<span id="record_pause_off" style="display:none">to <b>continue</b> recording</span>
2432</p>
2433
2434<p style="margin:4px 0 0 0; padding:0">
2435<span id="record_c" style="border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">c</span>
2436<span>to add checkpoint</span>
2437</p>
2438
2439<p style="margin:6px 0 0 0; padding:0">
2440checkpoints:
2441</p>
2442<div id="record_checkpoints" style="position:relative;width:100%;height:6em;overflow:auto;font: normal normal 8pt sans-serif; color:#000; text-align: left">
2443</div>
2444</div>
2445
2446</span>
2447</body></html>
Note: See TracBrowser for help on using the repository browser.