[ Index ]
 

Code source de PRADO 3.0.6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/tests/test_tools/selenium/core/scripts/ -> selenium-testrunner.js (source)

   1  /*
   2  * Copyright 2004 ThoughtWorks, Inc
   3  *
   4  *  Licensed under the Apache License, Version 2.0 (the "License");
   5  *  you may not use this file except in compliance with the License.
   6  *  You may obtain a copy of the License at
   7  *
   8  *      http://www.apache.org/licenses/LICENSE-2.0
   9  *
  10  *  Unless required by applicable law or agreed to in writing, software
  11  *  distributed under the License is distributed on an "AS IS" BASIS,
  12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13  *  See the License for the specific language governing permissions and
  14  *  limitations under the License.
  15  *
  16  */
  17  
  18  // An object representing the current test, used external
  19  var currentTest = null; // TODO: get rid of this global, which mirrors the htmlTestRunner.currentTest
  20  var selenium = null;
  21  
  22  var htmlTestRunner;
  23  var HtmlTestRunner = Class.create();
  24  Object.extend(HtmlTestRunner.prototype, {
  25      initialize: function() {
  26          this.metrics = new Metrics();
  27          this.controlPanel = new HtmlTestRunnerControlPanel();
  28          this.htmlTestSuite = null;
  29          this.testFailed = false;
  30          this.currentTest = null;
  31          this.runAllTests = false;
  32          this.appWindow = null;
  33          // we use a timeout here to make sure the LOG has loaded first, so we can see _every_ error
  34          setTimeout(function() {
  35              this.loadSuiteFrame();
  36          }.bind(this), 500);
  37      },
  38  
  39      markFailed: function() {
  40          this.testFailed = true;
  41          this.htmlTestSuite.markFailed();
  42      },
  43  
  44      loadSuiteFrame: function() {
  45          if (selenium == null) {
  46              selenium = Selenium.createForWindow(this._getApplicationWindow());
  47              this._registerCommandHandlers();
  48          }
  49          this.controlPanel.setHighlightOption();
  50          var testSuiteName = this.controlPanel.getTestSuiteName();
  51          if (testSuiteName) {
  52              suiteFrame.load(testSuiteName, this._onloadTestSuite.bind(this));
  53          }
  54      },
  55  
  56      _getApplicationWindow: function () {
  57          if (this.controlPanel.isMultiWindowMode()) {
  58              return this._getSeparateApplicationWindow();
  59          }
  60          return $('myiframe').contentWindow;
  61      },
  62  
  63      _getSeparateApplicationWindow: function () {
  64          if (this.appWindow == null) {
  65              this.appWindow = openSeparateApplicationWindow('TestRunner-splash.html');
  66          }
  67          return this.appWindow;
  68      },
  69  
  70      _onloadTestSuite:function () {
  71          this.htmlTestSuite = new HtmlTestSuite(suiteFrame.getDocument());
  72          if (! this.htmlTestSuite.isAvailable()) {
  73              return;
  74          }
  75          if (this.controlPanel.isAutomatedRun()) {
  76              htmlTestRunner.startTestSuite();
  77          } else if (this.controlPanel.getAutoUrl()) {
  78              //todo what is the autourl doing, left to check it out
  79              addLoadListener(this._getApplicationWindow(), this._startSingleTest.bind(this));
  80              this._getApplicationWindow().src = this.controlPanel.getAutoUrl();
  81          } else {
  82              this.htmlTestSuite.getSuiteRows()[0].loadTestCase();
  83          }
  84      },
  85  
  86      _startSingleTest:function () {
  87          removeLoadListener(getApplicationWindow(), this._startSingleTest.bind(this));
  88          var singleTestName = this.controlPanel.getSingleTestName();
  89          testFrame.load(singleTestName, this.startTest.bind(this));
  90      },
  91  
  92      _registerCommandHandlers: function () {
  93          this.commandFactory = new CommandHandlerFactory();
  94          this.commandFactory.registerAll(selenium);
  95      },
  96  
  97      startTestSuite: function() {
  98          this.controlPanel.reset();
  99          this.metrics.resetMetrics();
 100          this.htmlTestSuite.reset();
 101          this.runAllTests = true;
 102          this.runNextTest();
 103      },
 104  
 105      runNextTest: function () {
 106          if (!this.runAllTests) {
 107              return;
 108          }
 109          this.htmlTestSuite.runNextTestInSuite();
 110      },
 111  
 112      startTest: function () {
 113          this.controlPanel.reset();
 114          testFrame.scrollToTop();
 115          //todo: move testFailed and storedVars to TestCase
 116          this.testFailed = false;
 117          storedVars = new Object();
 118          this.currentTest = new HtmlRunnerTestLoop(testFrame.getCurrentTestCase(), this.metrics, this.commandFactory);
 119          currentTest = this.currentTest;
 120          this.currentTest.start();
 121      },
 122  
 123      runSingleTest:function() {
 124          this.runAllTests = false;
 125          this.metrics.resetMetrics();
 126          this.startTest();
 127      }
 128  });
 129  
 130  var FeedbackColors = Class.create();
 131  Object.extend(FeedbackColors, {
 132      passColor : "#ccffcc",
 133      doneColor : "#eeffee",
 134      failColor : "#ffcccc",
 135      workingColor : "#ffffcc",
 136      breakpointColor : "#cccccc"
 137  });
 138  
 139  
 140  var runInterval = 0;
 141  
 142  
 143  /** SeleniumFrame encapsulates an iframe element */
 144  var SeleniumFrame = Class.create();
 145  Object.extend(SeleniumFrame.prototype, {
 146  
 147      initialize : function(frame) {
 148          this.frame = frame;
 149          addLoadListener(this.frame, this._handleLoad.bind(this));
 150      },
 151  
 152      getDocument : function() {
 153          return this.frame.contentWindow.document;
 154      },
 155  
 156      _handleLoad: function() {
 157          this._onLoad();
 158          if (this.loadCallback) {
 159              this.loadCallback();
 160              this.loadCallback = null;
 161          }
 162      },
 163  
 164      _onLoad: function() {
 165      },
 166  
 167      scrollToTop : function() {
 168          this.frame.contentWindow.scrollTo(0, 0);
 169      },
 170  
 171      _setLocation: function(location) {
 172          if (browserVersion.isSafari) {
 173              // safari doesn't reload the page when the location equals to current location.
 174              // hence, set the location to blank so that the page will reload automatically.
 175              this.frame.src = "about:blank";
 176              this.frame.src = location;
 177          } else {
 178              this.frame.contentWindow.location.replace(location);
 179          }
 180      },
 181  
 182      load: function(/* url, [callback] */) {
 183          if (arguments.length > 1) {
 184              this.loadCallback = arguments[1];
 185  
 186          }
 187          this._setLocation(arguments[0]);
 188      }
 189  
 190  });
 191  
 192  /** HtmlTestFrame - encapsulates the test-case iframe element */
 193  var HtmlTestFrame = Class.create();
 194  Object.extend(HtmlTestFrame.prototype, SeleniumFrame.prototype);
 195  Object.extend(HtmlTestFrame.prototype, {
 196  
 197      _onLoad: function() {
 198          this.setCurrentTestCase();
 199      },
 200  
 201      setCurrentTestCase: function() {
 202          //todo: this is not good looking
 203          this.currentTestCase = new HtmlTestCase(this.getDocument(), htmlTestRunner.htmlTestSuite.getCurrentRow());
 204      },
 205  
 206      getCurrentTestCase: function() {
 207          return this.currentTestCase;
 208      }
 209  
 210  });
 211  
 212  function onSeleniumLoad() {
 213      suiteFrame = new SeleniumFrame(getSuiteFrame());
 214      testFrame = new HtmlTestFrame(getTestFrame());
 215      htmlTestRunner = new HtmlTestRunner();
 216  }
 217  
 218  
 219  var suiteFrame;
 220  var testFrame;
 221  function getSuiteFrame() {
 222      var f = $('testSuiteFrame');
 223      if (f == null) {
 224          f = top;
 225          // proxyInjection mode does not set myiframe
 226      }
 227      return f;
 228  }
 229  
 230  function getTestFrame() {
 231      var f = $('testFrame');
 232      if (f == null) {
 233          f = top;
 234          // proxyInjection mode does not set myiframe
 235      }
 236      return f;
 237  }
 238  
 239  var HtmlTestRunnerControlPanel = Class.create();
 240  Object.extend(HtmlTestRunnerControlPanel.prototype, URLConfiguration.prototype);
 241  Object.extend(HtmlTestRunnerControlPanel.prototype, {
 242      initialize: function() {
 243          this._acquireQueryString();
 244  
 245          this.runInterval = 0;
 246  
 247          this.highlightOption = $('highlightOption');
 248          this.pauseButton = $('pauseTest');
 249          this.stepButton = $('stepTest');
 250  
 251          this.highlightOption.onclick = (function() {
 252              this.setHighlightOption();
 253          }).bindAsEventListener(this);
 254          this.pauseButton.onclick = this.pauseCurrentTest.bindAsEventListener(this);
 255          this.stepButton.onclick = this.stepCurrentTest.bindAsEventListener(this);
 256  
 257          this.speedController = new Control.Slider('speedHandle', 'speedTrack', {
 258              range: $R(0, 1000),
 259              onSlide: this.setRunInterval.bindAsEventListener(this),
 260              onChange: this.setRunInterval.bindAsEventListener(this)
 261          });
 262  
 263          this._parseQueryParameter();
 264      },
 265  
 266      setHighlightOption: function () {
 267          var isHighlight = this.highlightOption.checked;
 268          selenium.browserbot.getCurrentPage().setHighlightElement(isHighlight);
 269      },
 270  
 271      _parseQueryParameter: function() {
 272          var tempRunInterval = this._getQueryParameter("runInterval");
 273          if (tempRunInterval) {
 274              this.setRunInterval(tempRunInterval);
 275          }
 276          this.highlightOption.checked = this._getQueryParameter("highlight");
 277      },
 278  
 279      setRunInterval: function(runInterval) {
 280          this.runInterval = runInterval;
 281      },
 282  
 283      setToPauseAtNextCommand: function() {
 284          this.runInterval = -1;
 285      },
 286  
 287      pauseCurrentTest: function () {
 288          this.setToPauseAtNextCommand();
 289          this._switchPauseButtonToContinue();
 290      },
 291  
 292      continueCurrentTest: function () {
 293          this.reset();
 294          currentTest.resume();
 295      },
 296  
 297      reset: function() {
 298          this.runInterval = this.speedController.value;
 299          this._switchContinueButtonToPause();
 300      },
 301  
 302      _switchContinueButtonToPause: function() {
 303          this.pauseButton.innerHTML = "Pause";
 304          this.pauseButton.onclick = this.pauseCurrentTest.bindAsEventListener(this);
 305      },
 306  
 307      _switchPauseButtonToContinue: function() {
 308          $('stepTest').disabled = false;
 309          this.pauseButton.innerHTML = "Continue";
 310          this.pauseButton.onclick = this.continueCurrentTest.bindAsEventListener(this);
 311      },
 312  
 313      stepCurrentTest: function () {
 314          this.setToPauseAtNextCommand();
 315          currentTest.resume();
 316      },
 317  
 318      isAutomatedRun: function() {
 319          return this._isQueryParameterTrue("auto");
 320      },
 321  
 322      shouldSaveResultsToFile: function() {
 323          return this._isQueryParameterTrue("save");
 324      },
 325  
 326      closeAfterTests: function() {
 327          return this._isQueryParameterTrue("close");
 328      },
 329  
 330      getTestSuiteName: function() {
 331          return this._getQueryParameter("test");
 332      },
 333  
 334      getSingleTestName: function() {
 335          return this._getQueryParameter("singletest");
 336      },
 337  
 338      getAutoUrl: function() {
 339          return this._getQueryParameter("autoURL");
 340      },
 341  
 342      getResultsUrl: function() {
 343          return this._getQueryParameter("resultsUrl");
 344      },
 345  
 346      _acquireQueryString: function() {
 347          if (this.queryString) return;
 348          if (browserVersion.isHTA) {
 349              var args = this._extractArgs();
 350              if (args.length < 2) return null;
 351              this.queryString = args[1];
 352          } else {
 353              this.queryString = location.search.substr(1);
 354          }
 355      }
 356  
 357  });
 358  
 359  
 360  var AbstractResultAwareRow = Class.create();
 361  Object.extend(AbstractResultAwareRow.prototype, {
 362  
 363      initialize: function(trElement) {
 364          this.trElement = trElement;
 365      },
 366  
 367      markWorking: function() {
 368          this.trElement.bgColor = FeedbackColors.workingColor;
 369          safeScrollIntoView(this.trElement);
 370      },
 371  
 372      markPassed: function() {
 373          this.trElement.bgColor = FeedbackColors.passColor;
 374      },
 375  
 376      markDone: function() {
 377          this.trElement.bgColor = FeedbackColors.doneColor;
 378      },
 379  
 380      markFailed: function() {
 381          this.trElement.bgColor = FeedbackColors.failColor;
 382      }
 383  
 384  });
 385  
 386  var HtmlTestCaseRow = Class.create();
 387  Object.extend(HtmlTestCaseRow.prototype, AbstractResultAwareRow.prototype);
 388  Object.extend(HtmlTestCaseRow.prototype, {
 389  
 390      getCommand: function () {
 391          return new SeleniumCommand(getText(this.trElement.cells[0]),
 392                  getText(this.trElement.cells[1]),
 393                  getText(this.trElement.cells[2]),
 394                  this.isBreakpoint());
 395      },
 396  
 397      markFailed: function(errorMsg) {
 398          this.trElement.bgColor = FeedbackColors.failColor;
 399          this.setMessage(errorMsg);
 400      },
 401  
 402      setMessage: function(message) {
 403          this.trElement.cells[2].innerHTML = message;
 404      },
 405  
 406      reset: function() {
 407          this.trElement.bgColor = '';
 408          var thirdCell = this.trElement.cells[2];
 409          if (thirdCell) {
 410              if (thirdCell.originalHTML) {
 411                  thirdCell.innerHTML = thirdCell.originalHTML;
 412              } else {
 413                  thirdCell.originalHTML = thirdCell.innerHTML;
 414              }
 415          }
 416      },
 417  
 418      onClick: function() {
 419          if (this.trElement.isBreakpoint == undefined) {
 420              this.trElement.isBreakpoint = true;
 421              this.trElement.beforeBackgroundColor = Element.getStyle(this.trElement, "backgroundColor");
 422              Element.setStyle(this.trElement, {"background-color" : FeedbackColors.breakpointColor});
 423          } else {
 424              this.trElement.isBreakpoint = undefined;
 425              Element.setStyle(this.trElement, {"background-color" : this.trElement.beforeBackgroundColor});
 426          }
 427      },
 428  
 429      addBreakpointSupport: function() {
 430          Element.setStyle(this.trElement, {"cursor" : "pointer"});
 431          this.trElement.onclick = function() {
 432              this.onClick();
 433          }.bindAsEventListener(this);
 434      },
 435  
 436      isBreakpoint: function() {
 437          if (this.trElement.isBreakpoint == undefined || this.trElement.isBreakpoint == null) {
 438              return false
 439          }
 440          return this.trElement.isBreakpoint;
 441      }
 442  });
 443  
 444  var HtmlTestSuiteRow = Class.create();
 445  Object.extend(HtmlTestSuiteRow.prototype, AbstractResultAwareRow.prototype);
 446  Object.extend(HtmlTestSuiteRow.prototype, {
 447  
 448      initialize: function(trElement, testFrame, htmlTestSuite) {
 449          this.trElement = trElement;
 450          this.testFrame = testFrame;
 451          this.htmlTestSuite = htmlTestSuite;
 452          this.link = trElement.getElementsByTagName("a")[0];
 453          this.link.onclick = this._onClick.bindAsEventListener(this);
 454      },
 455  
 456      reset: function() {
 457          this.trElement.bgColor = '';
 458      },
 459  
 460      _onClick: function() {
 461          // todo: just send a message to the testSuite
 462          this.loadTestCase(null);
 463          return false;
 464      },
 465  
 466      loadTestCase: function(onloadFunction) {
 467          this.htmlTestSuite.currentRowInSuite = this.trElement.rowIndex - 1;
 468          // If the row has a stored results table, use that
 469          var resultsFromPreviousRun = this.trElement.cells[1];
 470          if (resultsFromPreviousRun) {
 471              // this.testFrame.restoreTestCase(resultsFromPreviousRun.innerHTML);
 472              var testBody = this.testFrame.getDocument().body;
 473              testBody.innerHTML = resultsFromPreviousRun.innerHTML;
 474              testFrame.setCurrentTestCase();
 475              if (onloadFunction) {
 476                  onloadFunction();
 477              }
 478          } else {
 479              this.testFrame.load(this.link.href, onloadFunction);
 480          }
 481      },
 482  
 483      saveTestResults: function() {
 484          // todo: GLOBAL ACCESS!
 485          var resultHTML = this.testFrame.getDocument().body.innerHTML;
 486          if (!resultHTML) return;
 487  
 488          // todo: why create this div?
 489          var divElement = this.trElement.ownerDocument.createElement("div");
 490          divElement.innerHTML = resultHTML;
 491  
 492          var hiddenCell = this.trElement.ownerDocument.createElement("td");
 493          hiddenCell.appendChild(divElement);
 494          hiddenCell.style.display = "none";
 495  
 496          this.trElement.appendChild(hiddenCell);
 497      }
 498  
 499  });
 500  
 501  var HtmlTestSuite = Class.create();
 502  Object.extend(HtmlTestSuite.prototype, {
 503  
 504      initialize: function(suiteDocument) {
 505          this.suiteDocument = suiteDocument;
 506          this.suiteRows = this._collectSuiteRows();
 507          this.titleRow = this.getTestTable().rows[0];
 508          this.title = this.titleRow.cells[0].innerHTML;
 509          this.reset();
 510      },
 511  
 512      reset: function() {
 513          this.failed = false;
 514          this.currentRowInSuite = -1;
 515          this.titleRow.bgColor = '';
 516          this.suiteRows.each(function(row) {
 517              row.reset();
 518          });
 519      },
 520  
 521      getTitle: function() {
 522          return this.title;
 523      },
 524  
 525      getSuiteRows: function() {
 526          return this.suiteRows;
 527      },
 528  
 529      getTestTable: function() {
 530          var tables = $A(this.suiteDocument.getElementsByTagName("table"));
 531          return tables[0];
 532      },
 533  
 534      isAvailable: function() {
 535          return this.getTestTable() != null;
 536      },
 537  
 538      _collectSuiteRows: function () {
 539          var result = [];
 540          for (rowNum = 1; rowNum < this.getTestTable().rows.length; rowNum++) {
 541              var rowElement = this.getTestTable().rows[rowNum];
 542              result.push(new HtmlTestSuiteRow(rowElement, testFrame, this));
 543          }
 544          return result;
 545      },
 546  
 547      getCurrentRow: function() {
 548          return this.suiteRows[this.currentRowInSuite];
 549      },
 550  
 551      markFailed: function() {
 552          this.failed = true;
 553          this.titleRow.bgColor = FeedbackColors.failColor;
 554      },
 555  
 556      markDone: function() {
 557          if (!this.failed) {
 558              this.titleRow.bgColor = FeedbackColors.passColor;
 559          }
 560      },
 561  
 562      _startCurrentTestCase: function() {
 563          this.getCurrentRow().markWorking();
 564          this.getCurrentRow().loadTestCase(htmlTestRunner.startTest.bind(htmlTestRunner));
 565      },
 566  
 567      _onTestSuiteComplete: function() {
 568          this.markDone();
 569          new TestResult(this.failed, this.getTestTable()).post();
 570      },
 571  
 572      _updateSuiteWithResultOfPreviousTest: function() {
 573          if (this.currentRowInSuite >= 0) {
 574              this.getCurrentRow().saveTestResults();
 575          }
 576      },
 577  
 578      runNextTestInSuite: function() {
 579          this._updateSuiteWithResultOfPreviousTest();
 580          this.currentRowInSuite++;
 581  
 582          // If we are done with all of the tests, set the title bar as pass or fail
 583          if (this.currentRowInSuite >= this.suiteRows.length) {
 584              this._onTestSuiteComplete();
 585          } else {
 586              this._startCurrentTestCase();
 587          }
 588      }
 589  
 590  
 591  
 592  });
 593  
 594  var TestResult = Class.create();
 595  Object.extend(TestResult.prototype, {
 596  
 597  // Post the results to a servlet, CGI-script, etc.  The URL of the
 598  // results-handler defaults to "/postResults", but an alternative location
 599  // can be specified by providing a "resultsUrl" query parameter.
 600  //
 601  // Parameters passed to the results-handler are:
 602  //      result:         passed/failed depending on whether the suite passed or failed
 603  //      totalTime:      the total running time in seconds for the suite.
 604  //
 605  //      numTestPasses:  the total number of tests which passed.
 606  //      numTestFailures: the total number of tests which failed.
 607  //
 608  //      numCommandPasses: the total number of commands which passed.
 609  //      numCommandFailures: the total number of commands which failed.
 610  //      numCommandErrors: the total number of commands which errored.
 611  //
 612  //      suite:      the suite table, including the hidden column of test results
 613  //      testTable.1 to testTable.N: the individual test tables
 614  //
 615      initialize: function (suiteFailed, suiteTable) {
 616          this.controlPanel = htmlTestRunner.controlPanel;
 617          this.metrics = htmlTestRunner.metrics;
 618          this.suiteFailed = suiteFailed;
 619          this.suiteTable = suiteTable;
 620      },
 621  
 622      post: function () {
 623          if (!this.controlPanel.isAutomatedRun()) {
 624              return;
 625          }
 626          var form = document.createElement("form");
 627          document.body.appendChild(form);
 628  
 629          form.id = "resultsForm";
 630          form.method = "post";
 631          form.target = "myiframe";
 632  
 633          var resultsUrl = this.controlPanel.getResultsUrl();
 634          if (!resultsUrl) {
 635              resultsUrl = "./postResults";
 636          }
 637  
 638          var actionAndParameters = resultsUrl.split('?', 2);
 639          form.action = actionAndParameters[0];
 640          var resultsUrlQueryString = actionAndParameters[1];
 641  
 642          form.createHiddenField = function(name, value) {
 643              input = document.createElement("input");
 644              input.type = "hidden";
 645              input.name = name;
 646              input.value = value;
 647              this.appendChild(input);
 648          };
 649  
 650          if (resultsUrlQueryString) {
 651              var clauses = resultsUrlQueryString.split('&');
 652              for (var i = 0; i < clauses.length; i++) {
 653                  var keyValuePair = clauses[i].split('=', 2);
 654                  var key = unescape(keyValuePair[0]);
 655                  var value = unescape(keyValuePair[1]);
 656                  form.createHiddenField(key, value);
 657              }
 658          }
 659  
 660          form.createHiddenField("selenium.version", Selenium.version);
 661          form.createHiddenField("selenium.revision", Selenium.revision);
 662  
 663          form.createHiddenField("result", this.suiteFailed ? "failed" : "passed");
 664  
 665          form.createHiddenField("totalTime", Math.floor((this.metrics.currentTime - this.metrics.startTime) / 1000));
 666          form.createHiddenField("numTestPasses", this.metrics.numTestPasses);
 667          form.createHiddenField("numTestFailures", this.metrics.numTestFailures);
 668          form.createHiddenField("numCommandPasses", this.metrics.numCommandPasses);
 669          form.createHiddenField("numCommandFailures", this.metrics.numCommandFailures);
 670          form.createHiddenField("numCommandErrors", this.metrics.numCommandErrors);
 671  
 672          // Create an input for each test table.  The inputs are named
 673          // testTable.1, testTable.2, etc.
 674          for (rowNum = 1; rowNum < this.suiteTable.rows.length; rowNum++) {
 675              // If there is a second column, then add a new input
 676              if (this.suiteTable.rows[rowNum].cells.length > 1) {
 677                  var resultCell = this.suiteTable.rows[rowNum].cells[1];
 678                  form.createHiddenField("testTable." + rowNum, resultCell.innerHTML);
 679                  // remove the resultCell, so it's not included in the suite HTML
 680                  resultCell.parentNode.removeChild(resultCell);
 681              }
 682          }
 683  
 684          form.createHiddenField("numTestTotal", rowNum);
 685  
 686          // Add HTML for the suite itself
 687          form.createHiddenField("suite", this.suiteTable.parentNode.innerHTML);
 688  
 689          if (this.controlPanel.shouldSaveResultsToFile()) {
 690              this._saveToFile(resultsUrl, form);
 691          } else {
 692              form.submit();
 693          }
 694          document.body.removeChild(form);
 695          if (this.controlPanel.closeAfterTests()) {
 696              window.top.close();
 697          }
 698      },
 699  
 700      _saveToFile: function (fileName, form) {
 701          // This only works when run as an IE HTA
 702          var inputs = new Object();
 703          for (var i = 0; i < form.elements.length; i++) {
 704              inputs[form.elements[i].name] = form.elements[i].value;
 705          }
 706          var objFSO = new ActiveXObject("Scripting.FileSystemObject")
 707          var scriptFile = objFSO.CreateTextFile(fileName);
 708          scriptFile.WriteLine("<html><body>\n<h1>Test suite results </h1>" +
 709                               "\n\n<table>\n<tr>\n<td>result:</td>\n<td>" + inputs["result"] + "</td>\n" +
 710                               "</tr>\n<tr>\n<td>totalTime:</td>\n<td>" + inputs["totalTime"] + "</td>\n</tr>\n" +
 711                               "<tr>\n<td>numTestPasses:</td>\n<td>" + inputs["numTestPasses"] + "</td>\n</tr>\n" +
 712                               "<tr>\n<td>numTestFailures:</td>\n<td>" + inputs["numTestFailures"] + "</td>\n</tr>\n" +
 713                               "<tr>\n<td>numCommandPasses:</td>\n<td>" + inputs["numCommandPasses"] + "</td>\n</tr>\n" +
 714                               "<tr>\n<td>numCommandFailures:</td>\n<td>" + inputs["numCommandFailures"] + "</td>\n</tr>\n" +
 715                               "<tr>\n<td>numCommandErrors:</td>\n<td>" + inputs["numCommandErrors"] + "</td>\n</tr>\n" +
 716                               "<tr>\n<td>" + inputs["suite"] + "</td>\n<td>&nbsp;</td>\n</tr>");
 717          var testNum = inputs["numTestTotal"];
 718          for (var rowNum = 1; rowNum < testNum; rowNum++) {
 719              scriptFile.WriteLine("<tr>\n<td>" + inputs["testTable." + rowNum] + "</td>\n<td>&nbsp;</td>\n</tr>");
 720          }
 721          scriptFile.WriteLine("</table></body></html>");
 722          scriptFile.Close();
 723      }
 724  });
 725  
 726  /** HtmlTestCase encapsulates an HTML test document */
 727  var HtmlTestCase = Class.create();
 728  Object.extend(HtmlTestCase.prototype, {
 729  
 730      initialize: function(testDocument, htmlTestSuiteRow) {
 731          if (testDocument == null) {
 732              throw "testDocument should not be null";
 733          }
 734          if (htmlTestSuiteRow == null) {
 735              throw "htmlTestSuiteRow should not be null";
 736          }
 737          this.testDocument = testDocument;
 738          this.htmlTestSuiteRow = htmlTestSuiteRow;
 739          this.commandRows = this._collectCommandRows();
 740          this.nextCommandRowIndex = 0;
 741          this._addBreakpointSupport();
 742      },
 743  
 744      _collectCommandRows: function () {
 745          var commandRows = [];
 746          var tables = $A(this.testDocument.getElementsByTagName("table"));
 747          var self = this;
 748          tables.each(function (table) {
 749              $A(table.rows).each(function(candidateRow) {
 750                  if (self.isCommandRow(candidateRow)) {
 751                      commandRows.push(new HtmlTestCaseRow(candidateRow));
 752                  }
 753              }.bind(this));
 754          });
 755          return commandRows;
 756      },
 757  
 758      isCommandRow:  function (row) {
 759          return row.cells.length >= 3;
 760      },
 761  
 762      reset: function() {
 763          /**
 764           * reset the test to runnable state
 765           */
 766          this.nextCommandRowIndex = 0;
 767  
 768          this._setTitleColor('');
 769          this.commandRows.each(function(row) {
 770              row.reset();
 771          });
 772  
 773          // remove any additional fake "error" row added to the end of the document
 774          var errorElement = this.testDocument.getElementById('error');
 775          if (errorElement) {
 776              Element.remove(errorElement);
 777          }
 778      },
 779  
 780      getCommandRows: function () {
 781          return this.commandRows;
 782      },
 783  
 784      _setTitleColor: function(color) {
 785          var headerRow = this.testDocument.getElementsByTagName("tr")[0];
 786          if (headerRow) {
 787              headerRow.bgColor = color;
 788          }
 789      },
 790  
 791      markFailed: function() {
 792          this._setTitleColor(FeedbackColors.failColor);
 793          this.htmlTestSuiteRow.markFailed();
 794      },
 795  
 796      markPassed: function() {
 797          this._setTitleColor(FeedbackColors.passColor);
 798          this.htmlTestSuiteRow.markPassed();
 799      },
 800  
 801      addErrorMessage: function(errorMsg, currentRow) {
 802          if (currentRow) {
 803              currentRow.markFailed(errorMsg);
 804          } else {
 805              var errorElement = this.testDocument.createElement("p");
 806              errorElement.id = "error";
 807              errorElement.innerHTML = errorMsg;
 808              this.testDocument.body.appendChild(errorElement);
 809              Element.setStyle(errorElement, {'backgroundColor': FeedbackColors.failColor});
 810          }
 811      },
 812  
 813      _addBreakpointSupport: function() {
 814          this.commandRows.each(function(row) {
 815              row.addBreakpointSupport();
 816          });
 817      },
 818  
 819      hasMoreCommandRows: function() {
 820          return this.nextCommandRowIndex < this.commandRows.length;
 821      },
 822  
 823      getNextCommandRow: function() {
 824          if (this.hasMoreCommandRows()) {
 825              return this.commandRows[this.nextCommandRowIndex++];
 826          }
 827          return null;
 828      }
 829  
 830  });
 831  
 832  
 833  // TODO: split out an JavascriptTestCase class to handle the "sejs" stuff
 834  
 835  var get_new_rows = function() {
 836      var row_array = new Array();
 837      for (var i = 0; i < new_block.length; i++) {
 838  
 839          var new_source = (new_block[i][0].tokenizer.source.slice(new_block[i][0].start,
 840                  new_block[i][0].end));
 841  
 842          var row = '<td style="display:none;" class="js">getEval</td>' +
 843                    '<td style="display:none;">currentTest.doNextCommand()</td>' +
 844                    '<td style="white-space: pre;">' + new_source + '</td>' +
 845                    '<td></td>'
 846  
 847          row_array.push(row);
 848      }
 849      return row_array;
 850  };
 851  
 852  
 853  var Metrics = Class.create();
 854  Object.extend(Metrics.prototype, {
 855      initialize: function() {
 856          // The number of tests run
 857          this.numTestPasses = 0;
 858          // The number of tests that have failed
 859          this.numTestFailures = 0;
 860          // The number of commands which have passed
 861          this.numCommandPasses = 0;
 862          // The number of commands which have failed
 863          this.numCommandFailures = 0;
 864          // The number of commands which have caused errors (element not found)
 865          this.numCommandErrors = 0;
 866          // The time that the test was started.
 867          this.startTime = null;
 868          // The current time.
 869          this.currentTime = null;
 870      },
 871  
 872      printMetrics: function() {
 873          setText($('commandPasses'), this.numCommandPasses);
 874          setText($('commandFailures'), this.numCommandFailures);
 875          setText($('commandErrors'), this.numCommandErrors);
 876          setText($('testRuns'), this.numTestPasses + this.numTestFailures);
 877          setText($('testFailures'), this.numTestFailures);
 878  
 879          this.currentTime = new Date().getTime();
 880  
 881          var timeDiff = this.currentTime - this.startTime;
 882          var totalSecs = Math.floor(timeDiff / 1000);
 883  
 884          var minutes = Math.floor(totalSecs / 60);
 885          var seconds = totalSecs % 60;
 886  
 887          setText($('elapsedTime'), this._pad(minutes) + ":" + this._pad(seconds));
 888      },
 889  
 890  // Puts a leading 0 on num if it is less than 10
 891      _pad: function(num) {
 892          return (num > 9) ? num : "0" + num;
 893      },
 894  
 895      resetMetrics: function() {
 896          this.numTestPasses = 0;
 897          this.numTestFailures = 0;
 898          this.numCommandPasses = 0;
 899          this.numCommandFailures = 0;
 900          this.numCommandErrors = 0;
 901          this.startTime = new Date().getTime();
 902      }
 903  
 904  });
 905  
 906  var HtmlRunnerCommandFactory = Class.create();
 907  Object.extend(HtmlRunnerCommandFactory.prototype, {
 908  
 909      initialize: function(seleniumCommandFactory, testLoop) {
 910          this.seleniumCommandFactory = seleniumCommandFactory;
 911          this.testLoop = testLoop;
 912          this.handlers = {
 913              pause: {
 914                  execute: function(selenium, command) {
 915                      testLoop.pauseInterval = command.target;
 916                      return {};
 917                  }
 918              }
 919          };
 920          //todo: register commands
 921      },
 922  
 923      getCommandHandler: function(command) {
 924          if (this.handlers[command]) {
 925              return this.handlers[command];
 926          }
 927          return this.seleniumCommandFactory.getCommandHandler(command);
 928      }
 929  
 930  });
 931  
 932  var HtmlRunnerTestLoop = Class.create();
 933  Object.extend(HtmlRunnerTestLoop.prototype, new TestLoop());
 934  Object.extend(HtmlRunnerTestLoop.prototype, {
 935      initialize: function(htmlTestCase, metrics, seleniumCommandFactory) {
 936  
 937          this.commandFactory = new HtmlRunnerCommandFactory(seleniumCommandFactory, this);
 938          this.metrics = metrics;
 939  
 940          this.htmlTestCase = htmlTestCase;
 941  
 942          se = selenium;
 943          global.se = selenium;
 944  
 945          this.currentRow = null;
 946          this.currentRowIndex = 0;
 947  
 948          // used for selenium tests in javascript
 949          this.currentItem = null;
 950          this.commandAgenda = new Array();
 951  
 952          this.htmlTestCase.reset();
 953  
 954          this.sejsElement = this.htmlTestCase.testDocument.getElementById('sejs');
 955          if (this.sejsElement) {
 956              var fname = 'Selenium JavaScript';
 957              parse_result = parse(this.sejsElement.innerHTML, fname, 0);
 958  
 959              var x2 = new ExecutionContext(GLOBAL_CODE);
 960              ExecutionContext.current = x2;
 961  
 962              execute(parse_result, x2)
 963          }
 964      },
 965  
 966      _advanceToNextRow: function() {
 967          if (this.htmlTestCase.hasMoreCommandRows()) {
 968              this.currentRow = this.htmlTestCase.getNextCommandRow();
 969              if (this.sejsElement) {
 970                  this.currentItem = agenda.pop();
 971                  this.currentRowIndex++;
 972              }
 973          } else {
 974              this.currentRow = null;
 975              this.currentItem = null;
 976          }
 977      },
 978  
 979      nextCommand : function() {
 980          this._advanceToNextRow();
 981          if (this.currentRow == null) {
 982              return null;
 983          }
 984          return this.currentRow.getCommand();
 985      },
 986  
 987      commandStarted : function() {
 988          $('pauseTest').disabled = false;
 989          this.currentRow.markWorking();
 990          this.metrics.printMetrics();
 991      },
 992  
 993      commandComplete : function(result) {
 994          if (result.failed) {
 995              this.metrics.numCommandFailures += 1;
 996              this._recordFailure(result.failureMessage);
 997          } else if (result.passed) {
 998              this.metrics.numCommandPasses += 1;
 999              this.currentRow.markPassed();
1000          } else {
1001              this.currentRow.markDone();
1002          }
1003      },
1004  
1005      commandError : function(errorMessage) {
1006          this.metrics.numCommandErrors += 1;
1007          this._recordFailure(errorMessage);
1008      },
1009  
1010      _recordFailure : function(errorMsg) {
1011          LOG.warn("currentTest.recordFailure: " + errorMsg);
1012          htmlTestRunner.markFailed();
1013          this.htmlTestCase.addErrorMessage(errorMsg, this.currentRow);
1014      },
1015  
1016      testComplete : function() {
1017          $('pauseTest').disabled = true;
1018          $('stepTest').disabled = true;
1019          if (htmlTestRunner.testFailed) {
1020              this.htmlTestCase.markFailed();
1021              this.metrics.numTestFailures += 1;
1022          } else {
1023              this.htmlTestCase.markPassed();
1024              this.metrics.numTestPasses += 1;
1025          }
1026  
1027          this.metrics.printMetrics();
1028  
1029          window.setTimeout(function() {
1030              htmlTestRunner.runNextTest();
1031          }, 1);
1032      },
1033  
1034      getCommandInterval : function() {
1035          return htmlTestRunner.controlPanel.runInterval;
1036      },
1037  
1038      pause : function() {
1039          htmlTestRunner.controlPanel.pauseCurrentTest();
1040      },
1041  
1042      doNextCommand: function() {
1043          var _n = this.currentItem[0];
1044          var _x = this.currentItem[1];
1045  
1046          new_block = new Array()
1047          execute(_n, _x);
1048          if (new_block.length > 0) {
1049              var the_table = this.htmlTestCase.testDocument.getElementById("se-js-table")
1050              var loc = this.currentRowIndex
1051              var new_rows = get_new_rows()
1052  
1053              // make the new statements visible on screen...
1054              for (var i = 0; i < new_rows.length; i++) {
1055                  the_table.insertRow(loc + 1);
1056                  the_table.rows[loc + 1].innerHTML = new_rows[i];
1057                  this.commandRows.unshift(the_table.rows[loc + 1])
1058              }
1059  
1060          }
1061      }
1062  
1063  });
1064  
1065  
1066  Selenium.prototype.doBreak = function() {
1067      /** Halt the currently running test, and wait for the user to press the Continue button.
1068       * This command is useful for debugging, but be careful when using it, because it will
1069       * force automated tests to hang until a user intervenes manually.
1070       */
1071      // todo: should not refer to controlPanel directly
1072      htmlTestRunner.controlPanel.setToPauseAtNextCommand();
1073  };
1074  
1075  Selenium.prototype.doStore = function(expression, variableName) {
1076      /** This command is a synonym for storeExpression.
1077       * @param expression the value to store
1078       * @param variableName the name of a <a href="#storedVars">variable</a> in which the result is to be stored.
1079       */
1080      storedVars[variableName] = expression;
1081  }
1082  
1083  /*
1084   * Click on the located element, and attach a callback to notify
1085   * when the page is reloaded.
1086   */
1087  // DGF TODO this code has been broken for some time... what is it trying to accomplish?
1088  Selenium.prototype.XXXdoModalDialogTest = function(returnValue) {
1089      this.browserbot.doModalDialogTest(returnValue);
1090  };
1091  
1092  Selenium.prototype.doEcho = function(message) {
1093      /** Prints the specified message into the third table cell in your Selenese tables.
1094       * Useful for debugging.
1095       * @param message the message to print
1096       */
1097      currentTest.currentRow.setMessage(message);
1098  }
1099  
1100  Selenium.prototype.assertSelected = function(selectLocator, optionLocator) {
1101      /**
1102       * Verifies that the selected option of a drop-down satisfies the optionSpecifier.  <i>Note that this command is deprecated; you should use assertSelectedLabel, assertSelectedValue, assertSelectedIndex, or assertSelectedId instead.</i>
1103       *
1104       * <p>See the select command for more information about option locators.</p>
1105       *
1106       * @param selectLocator an <a href="#locators">element locator</a> identifying a drop-down menu
1107       * @param optionLocator an option locator, typically just an option label (e.g. "John Smith")
1108       */
1109      var element = this.page().findElement(selectLocator);
1110      var locator = this.optionLocatorFactory.fromLocatorString(optionLocator);
1111      if (element.selectedIndex == -1)
1112      {
1113          Assert.fail("No option selected");
1114      }
1115      locator.assertSelected(element);
1116  };
1117  
1118  /**
1119   * Tell Selenium to expect a failure on the next command execution. This
1120   * command temporarily installs a CommandFactory that generates
1121   * CommandHandlers that expect a failure.
1122   */
1123  Selenium.prototype.assertFailureOnNext = function(message) {
1124      if (!message) {
1125          throw new Error("Message must be provided");
1126      }
1127  
1128      var expectFailureCommandFactory =
1129          new ExpectFailureCommandFactory(currentTest.commandFactory, message, "failure", executeCommandAndReturnFailureMessage);
1130      currentTest.commandFactory = expectFailureCommandFactory;
1131  };
1132  
1133  /**
1134   * Tell Selenium to expect an error on the next command execution. This
1135   * command temporarily installs a CommandFactory that generates
1136   * CommandHandlers that expect a failure.
1137   */
1138  Selenium.prototype.assertErrorOnNext = function(message) {
1139      if (!message) {
1140          throw new Error("Message must be provided");
1141      }
1142  
1143      var expectFailureCommandFactory =
1144          new ExpectFailureCommandFactory(currentTest.commandFactory, message, "error", executeCommandAndReturnErrorMessage);
1145      currentTest.commandFactory = expectFailureCommandFactory;
1146  };
1147  
1148  function executeCommandAndReturnFailureMessage(baseHandler, originalArguments) {
1149      var baseResult = baseHandler.execute.apply(baseHandler, originalArguments);
1150      if (baseResult.passed) {
1151          return null;
1152      }
1153      return baseResult.failureMessage;
1154  };
1155  
1156  function executeCommandAndReturnErrorMessage(baseHandler, originalArguments) {
1157      try {
1158          baseHandler.execute.apply(baseHandler, originalArguments);
1159          return null;
1160      }
1161      catch (expected) {
1162          return expected.message;
1163      }
1164  };
1165  
1166  function ExpectFailureCommandHandler(baseHandler, originalCommandFactory, expectedErrorMessage, errorType, decoratedExecutor) {
1167      this.execute = function() {
1168          var baseFailureMessage = decoratedExecutor(baseHandler, arguments);
1169          var result = {};
1170          if (!baseFailureMessage) {
1171              result.failed = true;
1172              result.failureMessage = "Expected " + errorType + " did not occur.";
1173          }
1174          else {
1175              if (! PatternMatcher.matches(expectedErrorMessage, baseFailureMessage)) {
1176                  result.failed = true;
1177                  result.failureMessage = "Expected " + errorType + " message '" + expectedErrorMessage
1178                                          + "' but was '" + baseFailureMessage + "'";
1179              }
1180              else {
1181                  result.passed = true;
1182                  result.result = baseFailureMessage;
1183              }
1184          }
1185          currentTest.commandFactory = originalCommandFactory;
1186          return result;
1187      };
1188  }
1189  
1190  function ExpectFailureCommandFactory(originalCommandFactory, expectedErrorMessage, errorType, decoratedExecutor) {
1191      this.getCommandHandler = function(name) {
1192          var baseHandler = originalCommandFactory.getCommandHandler(name);
1193          return new ExpectFailureCommandHandler(baseHandler, originalCommandFactory, expectedErrorMessage, errorType, decoratedExecutor);
1194      };
1195  };


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7