QGUITestRunner.pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:39k
源码类别:

Email服务器

开发平台:

Delphi

  1. { $Id: QGUITestRunner.pas,v 1.16 2006/07/19 02:45:55 judc Exp $ }
  2. {: DUnit: An XTreme testing framework for Delphi programs.
  3.   @author  The DUnit Group.
  4.   @version $Revision: 1.16 $ 2001/03/08 uberto
  5. }
  6. (*
  7.  * The contents of this file are subject to the Mozilla Public
  8.  * License Version 1.1 (the "License"); you may not use this file
  9.  * except in compliance with the License. You may obtain a copy of
  10.  * the License at http://www.mozilla.org/MPL/
  11.  *
  12.  * Software distributed under the License is distributed on an "AS
  13.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  14.  * implied. See the License for the specific language governing
  15.  * rights and limitations under the License.
  16.  *
  17.  * The Original Code is DUnit.
  18.  *
  19.  * The Initial Developers of the Original Code are Kent Beck, Erich Gamma,
  20.  * and Juancarlo A眅z.
  21.  * Portions created The Initial Developers are Copyright (C) 1999-2000.
  22.  * Portions created by The DUnit Group are Copyright (C) 2000-2003.
  23.  * All rights reserved.
  24.  *
  25.  * Contributor(s):
  26.  * Kent Beck <kentbeck@csi.com>
  27.  * Erich Gamma <Erich_Gamma@oti.com>
  28.  * Juanco A馿z <juanco@users.sourceforge.net>
  29.  * Chris Morris <chrismo@users.sourceforge.net>
  30.  * Jeff Moore <JeffMoore@users.sourceforge.net>
  31.  * Kenneth Semeijn <dunit@designtime.demon.nl>
  32.  * Uberto Barbini <uberto@usa.net>
  33.  * Brett Shearer <BrettShearer@users.sourceforge.net>
  34.  * Kris Golko <neuromancer@users.sourceforge.net>
  35.  * The DUnit group at SourceForge <http://dunit.sourceforge.net>
  36.  *
  37.  *)
  38. unit QGUITestRunner;
  39. interface
  40. uses
  41.   TestFramework, Math,
  42.   Types, QForms, QGraphics, QMenus, QTypes, QActnList, QImgList,
  43.   QStdCtrls, QComCtrls, QControls, QExtCtrls,
  44.   SysUtils, Classes, IniFiles;
  45. const
  46.   {: Section of the dunit.ini file where GUI information will be stored }
  47.   cnConfigIniSection = 'GUITestRunner Config';
  48.   {: Color constants for the progress bar and failure details panel }
  49.   clOK      = clGreen;
  50.   clFAILURE = clFuchsia;
  51.   clERROR   = clRed;
  52.   {: Indexes of the color images used in the test tree and failure list }
  53.   imgNONE    = 0;
  54.   imgRUNNING = 1;
  55.   imgRUN     = 2;
  56.   imgFAILED  = 3;
  57.   imgERROR   = 4;
  58.   {: Indexes of the images used for test tree checkboxes }
  59.   imgRangeEnabled         = 0;
  60.   imgRangeDisabled        = 1;
  61.   imgRangeParentDisabled  = 2;
  62. type
  63.   {: Function type used by the TDUnitDialog.ApplyToTests method
  64.     @param item  The ITest instance on which to act
  65.     @return true if processing should continue, false otherwise
  66.   }
  67.   TTestFunc = function (item :ITest):boolean of object;
  68.   TGUITestRunner = class(TForm, ITestListener, ITestListenerX)
  69.    StateImages: TImageList;
  70.    RunImages: TImageList;
  71.    DialogActions: TActionList;
  72.    SelectAllAction: TAction;
  73.    DeselectAllAction: TAction;
  74.    SelectFailedAction: TAction;
  75.    MainMenu: TMainMenu;
  76.    TestTreeMenu: TMenuItem;
  77.    SelectAllItem: TMenuItem;
  78.    DeselectAllItem: TMenuItem;
  79.    SelectFailedItem: TMenuItem;
  80.    FileMenu: TMenuItem;
  81.    SaveConfigurationAction: TAction;
  82.    AutoSaveAction: TAction;
  83.    SaveConfigurationItem: TMenuItem;
  84.    AutoSaveItem: TMenuItem;
  85.    RestoreSavedAction: TAction;
  86.    RestoreSavedConfigurationItem: TMenuItem;
  87.    ViewMenu: TMenuItem;
  88.    HideErrorBoxItem: TMenuItem;
  89.    BodyPanel: TPanel;
  90.    ErrorBoxVisibleAction: TAction;
  91.    TopPanel: TPanel;
  92.    TreePanel: TPanel;
  93.    TestTree: TTreeView;
  94.    ResultsPanel: TPanel;
  95.    ProgressPanel: TPanel;
  96.    ResultsView: TListView;
  97.    FailureListView: TListView;
  98.    ErrorBoxPanel: TPanel;
  99.    ErrorBoxSplitter: TSplitter;
  100.    ResultsSplitter: TSplitter;
  101.    AutoChangeFocusItem: TMenuItem;
  102.    TopProgressPanel: TPanel;
  103.    ProgressBar: TProgressBar;
  104.    pnlProgresslabel: TPanel;
  105.    ScorePanel: TPanel;
  106.    ScoreLabel: TPanel;
  107.    ScoreBar: TProgressBar;
  108.    HideTestNodesAction: TAction;
  109.    CollapseLowestSuiteNodesItem: TMenuItem;
  110.    HideTestNodesOnOpenAction: TAction;
  111.    HideTestNodesItem: TMenuItem;
  112.    ExpandAllNodesAction: TAction;
  113.    TestTreeMenuSeparator: TMenuItem;
  114.    ExpandAllItem: TMenuItem;
  115.    lblTestTree: TLabel;
  116.    RunAction: TAction;
  117.    ExitAction: TAction;
  118.    BreakOnFailuresAction: TAction;
  119.    BreakonFailuresItem: TMenuItem;
  120.    ShowTestedNodeAction: TAction;
  121.    SelectTestedNodeItem: TMenuItem;
  122.    pmErrorMessage: TPopupMenu;
  123.    CopyFailureMessage: TMenuItem;
  124.    CopyMessageToClipboardAction: TAction;
  125.    ActionsMenu: TMenuItem;
  126.    CopyMessagetoCllipboardItem: TMenuItem;
  127.    LbProgress: TLabel;
  128.    UseRegistryAction: TAction;
  129.    UseRegistryItem: TMenuItem;
  130.    SelectCurrentAction: TAction;
  131.    DeselectCurrentAction: TAction;
  132.    SelectCurrent1: TMenuItem;
  133.    DeselectCurrent1: TMenuItem;
  134.    ActionsImages: TImageList;
  135.    CloseItem: TMenuItem;
  136.    Run1: TMenuItem;
  137.    StopAction: TAction;
  138.    StopActionItem: TMenuItem;
  139.    ToolBar1: TToolBar;
  140.    SelectAllButton: TToolButton;
  141.    DeselectAllButton: TToolButton;
  142.    ToolButton1: TToolButton;
  143.    SelectFailedButton: TToolButton;
  144.    ToolButton2: TToolButton;
  145.    SelectCurrentButton: TToolButton;
  146.    DeselectCurrentButton: TToolButton;
  147.    ToolButton3: TToolButton;
  148.    ToolButton4: TToolButton;
  149.    ToolButton5: TToolButton;
  150.    Alt_R_RunAction: TAction;
  151.    Alt_S_StopAction: TAction;
  152.     FailureTitlePanel: TPanel;
  153.     TestNameLabel: TLabel;
  154.     ErrorTypeLabel: TLabel;
  155.     MessageLabel: TLabel;
  156.     RunSelectedTestAction: TAction;
  157.     Runselectedtest1: TMenuItem;
  158.     RunSelectedTestToolButton: TToolButton;
  159.    procedure FormCreate(Sender: TObject);
  160.    procedure TestTreeClick(Sender: TObject);
  161.    procedure FailureListViewSelectItem(Sender: TObject; Item: TListItem;
  162.     Selected: Boolean);
  163.    procedure FailureListViewClick(Sender: TObject);
  164.    procedure TestTreeKeyPress(Sender: TObject; var Key: Char);
  165.    procedure SelectAllActionExecute(Sender: TObject);
  166.    procedure DeselectAllActionExecute(Sender: TObject);
  167.    procedure SelectFailedActionExecute(Sender: TObject);
  168.    procedure SaveConfigurationActionExecute(Sender: TObject);
  169.    procedure RestoreSavedActionExecute(Sender: TObject);
  170.    procedure AutoSaveActionExecute(Sender: TObject);
  171.    procedure ErrorBoxVisibleActionExecute(Sender: TObject);
  172.    procedure ErrorBoxSplitterMoved(Sender: TObject);
  173.    procedure ErrorBoxPanelResize(Sender: TObject);
  174.    procedure HideTestNodesActionExecute(Sender: TObject);
  175.    procedure HideTestNodesOnOpenActionExecute(Sender: TObject);
  176.    procedure ExpandAllNodesActionExecute(Sender: TObject);
  177.    procedure RunActionExecute(Sender: TObject);
  178.    procedure ExitActionExecute(Sender: TObject);
  179.    procedure BreakOnFailuresActionExecute(Sender: TObject);
  180.    procedure FormDestroy(Sender: TObject);
  181.    procedure ShowTestedNodeActionExecute(Sender: TObject);
  182.    procedure UseRegistryActionExecute(Sender: TObject);
  183.    procedure RunActionUpdate(Sender: TObject);
  184.    procedure CopyMessageToClipboardActionUpdate(Sender: TObject);
  185.    procedure SelectCurrentActionExecute(Sender: TObject);
  186.    procedure DeselectCurrentActionExecute(Sender: TObject);
  187.    procedure StopActionExecute(Sender: TObject);
  188.    procedure StopActionUpdate(Sender: TObject);
  189.    procedure TestTreeChange(Sender: TObject; Node: TTreeNode);
  190.    procedure RunSelectedTestActionExecute(Sender: TObject);
  191.    procedure RunSelectedTestActionUpdate(Sender: TObject);
  192.    procedure FormShow(Sender: TObject);
  193.   private
  194.    procedure ResetProgress;
  195.   protected
  196.     FSuite:       ITest;
  197.     FTestResult:  TTestResult;
  198.     FRunning:     Boolean;
  199.     FTests:       TInterfaceList;
  200.     FSelectedTests: TInterfaceList;
  201.    procedure Setup;
  202.    procedure SetUpStateImages;
  203.    procedure SetSuite(value: ITest);
  204.    procedure ClearResult;
  205.    procedure DisplayFailureMessage(Item :TListItem);
  206.    procedure ClearFailureMessage;
  207.    function  AddFailureItem(failure: TTestFailure): TListItem;
  208.    procedure UpdateStatus(const fullUpdate:Boolean);
  209.    procedure FillTestTree(RootNode: TTreeNode; ATest: ITest); overload;
  210.    procedure FillTestTree(ATest: ITest);                      overload;
  211.    procedure UpdateNodeImage(node: TTreeNode);
  212.    procedure UpdateNodeState(node: TTreeNode);
  213.    procedure SetNodeState(node: TTreeNode; enabled :boolean);
  214.    procedure SwitchNodeState(node: TTreeNode);
  215.    procedure UpdateTestTreeState;
  216.    procedure MakeNodeVisible(node :TTreeNode);
  217.    procedure SetTreeNodeImage(Node :TTReeNode; imgIndex :Integer);
  218.     function  NodeToTest(node :TTreeNode) :ITest;
  219.     function  TestToNode(test :ITest) :TTreeNode;
  220.     function  SelectedTest :ITest;
  221.     procedure ListSelectedTests;
  222.    function  EnableTest(test :ITest) : boolean;
  223.    function  DisableTest(test :ITest) : boolean;
  224.    procedure ApplyToTests(root :TTreeNode; const func :TTestFunc);
  225.     procedure EnableUI(enable :Boolean);
  226.     procedure RunTheTest(aTest: ITest);
  227.    procedure InitTree; virtual;
  228.    function  IniFileName :string;
  229.    function  GetIniFile( const FileName : string ) : tCustomIniFile;
  230.    procedure LoadRegistryAction;
  231.    procedure SaveRegistryAction;
  232.    procedure LoadFormPlacement;
  233.    procedure SaveFormPlacement;
  234.    procedure SaveConfiguration;
  235.    procedure LoadConfiguration;
  236.    procedure LoadSuiteConfiguration;
  237.    procedure AutoSaveConfiguration;
  238.    function NodeIsGrandparent(ANode: TTreeNode): boolean;
  239.    procedure CollapseNonGrandparentNodes(RootNode: TTreeNode);
  240.    procedure ProcessClickOnStateIcon;
  241.   public
  242.    {: implement the ITestListener interface }
  243.     procedure AddSuccess(test: ITest);
  244.     procedure AddError(failure: TTestFailure);
  245.     procedure AddFailure(failure: TTestFailure);
  246.     function  ShouldRunTest(test :ITest):boolean;
  247.     procedure StartSuite(suite: ITest); virtual;
  248.     procedure EndSuite(suite: ITest); virtual;
  249.     procedure StartTest(test: ITest);
  250.     procedure EndTest(test: ITest);
  251.     procedure TestingStarts;
  252.     procedure TestingEnds(testResult :TTestResult);
  253.     procedure Status(test :ITest; const Msg :string);
  254.     procedure Warning(test :ITest; const Msg :string);
  255.     class procedure RunTest(test: ITest);
  256.     class procedure RunTestModeless(test: ITest);
  257.     class procedure RunRegisteredTests;
  258.     class procedure RunRegisteredTestsModeless;
  259.    {: The test suite to be run in this runner }
  260.    property Suite: ITest read FSuite write SetSuite;
  261.    {: The result of the last test run }
  262.    property TestResult : TTestResult read FTestResult write FTestResult;
  263.   end;
  264. procedure RunTest(test: ITest);
  265. procedure RunRegisteredTests;
  266. procedure RunTestModeless(test: ITest);
  267. procedure RunRegisteredTestsModeless;
  268. implementation
  269. {$R *.xfm}
  270. type
  271.   TProgressBarCrack = class(TProgressBar);
  272. const
  273.   RUN_IMAGES_COUNT = 5;
  274. function NodeRunImageIndex(node: TTreeNode): integer;
  275. begin
  276.   Result := node.ImageIndex mod RUN_IMAGES_COUNT;
  277. end;
  278. function NodeStateImageIndex(node: TTreeNode): integer;
  279. begin
  280.   Result := node.ImageIndex div RUN_IMAGES_COUNT;
  281. end;
  282. function CalcImageIndex(StateImageIndex, RunImageIndex: integer): integer;
  283. begin
  284.   Result := StateImageIndex * RUN_IMAGES_COUNT + RunImageIndex;
  285. end;
  286. procedure RunTest(test: ITest);
  287. begin
  288.   TGUITestRunner.RunTest(test);
  289. end;
  290. procedure RunRegisteredTests;
  291. begin
  292.   TGUITestRunner.RunTest(registeredTests)
  293. end;
  294. procedure RunTestModeless(test: ITest);
  295. begin
  296.   TGUITestRunner.RunTestModeless(test);
  297. end;
  298. procedure RunRegisteredTestsModeless;
  299. begin
  300.   TGUITestRunner.RunRegisteredTestsModeless;
  301. end;
  302. { TGUITestRunner }
  303. class procedure TGUITestRunner.RunTest(test: ITest);
  304. begin
  305.   with TGUITestRunner.Create(nil) do
  306.   begin
  307.    try
  308.     suite := test;
  309.     ShowModal;
  310.    finally
  311.     Free;
  312.    end;
  313.   end;
  314. end;
  315. class procedure TGUITestRunner.RunTestModeless(test: ITest);
  316. var
  317.   GUI :TGUITestRunner;
  318. begin
  319.   Application.CreateForm(TGUITestRunner, GUI);
  320.   GUI.Suite := test;
  321.   GUI.Show;
  322. end;
  323. class procedure TGUITestRunner.RunRegisteredTests;
  324. begin
  325.   RunTest(registeredTests);
  326. end;
  327. class procedure TGUITestRunner.RunRegisteredTestsModeless;
  328. begin
  329.   TGUITestRunner.RunTestModeless(registeredTests);
  330. end;
  331. procedure TGUITestRunner.EndSuite(suite: ITest);
  332. begin
  333.   UpdateStatus(True);
  334. end;
  335. procedure TGUITestRunner.StartSuite(suite: ITest);
  336. begin
  337. end;
  338. procedure TGUITestRunner.InitTree;
  339. begin
  340.   FTests.Clear;
  341.   FillTestTree(FSuite);
  342.     Setup;
  343.     if HideTestNodesOnOpenAction.Checked then
  344.       HideTestNodesAction.Execute
  345.     else
  346.       ExpandAllNodesAction.Execute;
  347.     TestTree.Selected := TestTree.Items.GetFirstNode;
  348.   end;
  349. function TGUITestRunner.NodeToTest(Node: TTreeNode): ITest;
  350. var
  351.   index: Integer;
  352. begin
  353.   assert(assigned(Node));
  354.   index  := Integer(Node.data);
  355.   assert((index >= 0) and (index < FTests.Count));
  356.   result := FTests[index] as ITest;
  357. end;
  358. function TGUITestRunner.TestToNode(test: ITest): TTreeNode;
  359. begin
  360.   assert(assigned(test));
  361.   Result := TTreeNode(test.GUIObject);
  362.   assert(assigned(Result));
  363. end;
  364. function TGUITestRunner.SelectedTest: ITest;
  365. begin
  366.   if TestTree.Selected = nil then
  367.     Result := nil
  368.   else
  369.     Result := NodeToTest(TestTree.Selected);
  370. end;
  371. procedure TGUITestRunner.ListSelectedTests;
  372. var
  373.   aTest: ITest;
  374.   aNode: TTreeNode;
  375. begin
  376.   FreeAndNil(FSelectedTests);
  377.   FSelectedTests := TInterfaceList.Create;
  378.   aNode := TestTree.Selected;
  379.   while Assigned(aNode) do
  380.   begin
  381.     aTest := NodeToTest(aNode);
  382.     FSelectedTests.Add(aTest as ITest);
  383.     aNode := aNode.Parent;
  384.   end;
  385. end;
  386. function TGUITestRunner.ShouldRunTest(test: ITest): boolean;
  387. begin
  388.   if FSelectedTests = nil then
  389.     Result := test.Enabled
  390.   else
  391.     Result := FSelectedTests.IndexOf(test as ITest) >= 0;
  392. end;
  393. procedure TGUITestRunner.StartTest(test: ITest);
  394. var
  395.   node :TTreeNode;
  396. begin
  397.   assert(assigned(testResult));
  398.   assert(assigned(test));
  399.   node := TestToNode(test);
  400.   assert(assigned(node));
  401.   SetTreeNodeImage(node, imgRunning);
  402.   if ShowTestedNodeAction.Checked then
  403.   begin
  404.    MakeNodeVisible(node);
  405.    TestTree.Update;
  406.   end;
  407.   UpdateStatus(False);
  408. end;
  409. procedure TGUITestRunner.EndTest(test: ITest);
  410. begin
  411.   UpdateStatus(False);
  412. end;
  413. procedure TGUITestRunner.TestingStarts;
  414. begin
  415.   UpdateStatus(True);
  416.   TProgressBarCrack(ScoreBar).Color := clOK;
  417. end;
  418. procedure TGUITestRunner.AddSuccess(test: ITest);
  419. begin
  420.   assert(assigned(test));
  421.   SetTreeNodeImage(TestToNode(Test), imgRun);
  422. end;
  423. procedure TGUITestRunner.AddError(failure: TTestFailure);
  424. var
  425.   ListItem: TListItem;
  426. begin
  427.   ListItem := AddFailureItem(failure);
  428.   ListItem.ImageIndex := imgERROR;
  429.   TProgressBarCrack(ScoreBar).Color := clERROR;
  430.   SetTreeNodeImage(TestToNode(failure.failedTest), imgERROR);
  431.   UpdateStatus(False);
  432. end;
  433. procedure TGUITestRunner.AddFailure(failure: TTestFailure);
  434. var
  435.   ListItem: TListItem;
  436. begin
  437.   ListItem := AddFailureItem(failure);
  438.   ListItem.ImageIndex := imgFAILED;
  439.   if testResult.errorCount = 0 then
  440.   begin
  441.     TProgressBarCrack(ScoreBar).Color := clFAILURE;
  442.   end;
  443.   SetTreeNodeImage(TestToNode(failure.failedTest), imgFAILED);
  444.   UpdateStatus(False);
  445. end;
  446. function TGUITestRunner.IniFileName: string;
  447. const
  448.   TEST_INI_FILE = 'dunit.ini';
  449. begin
  450.    result := ExtractFilePath(ParamStr(0)) + TEST_INI_FILE
  451. end;
  452. procedure TGUITestRunner.LoadFormPlacement;
  453. begin
  454.   with GetIniFile( IniFileName ) do
  455.   try
  456.    Self.SetBounds(
  457.              ReadInteger(cnConfigIniSection, 'Left',   Left),
  458.              ReadInteger(cnConfigIniSection, 'Top',    Top),
  459.              ReadInteger(cnConfigIniSection, 'Width',  Width),
  460.              ReadInteger(cnConfigIniSection, 'Height', Height)
  461.              );
  462.    if ReadBool(cnConfigIniSection, 'Maximized', False ) then
  463.     WindowState := wsMaximized;
  464.   finally
  465.    Free;
  466.   end;
  467. end;
  468. procedure TGUITestRunner.SaveFormPlacement;
  469. begin
  470.   with GetIniFile(IniFileName) do
  471.   try
  472.     WriteBool(cnConfigIniSection, 'AutoSave', AutoSaveAction.Checked);
  473.       if WindowState <> wsMaximized then
  474.       begin
  475.         WriteInteger(cnConfigIniSection, 'Left',   Left);
  476.   WriteInteger(cnConfigIniSection, 'Top',    Top);
  477.   WriteInteger(cnConfigIniSection, 'Width',  Width);
  478.   WriteInteger(cnConfigIniSection, 'Height', Height );
  479.   WriteBool(cnConfigIniSection, 'Maximized', WindowState = wsMaximized );
  480.       end;
  481.   finally
  482.     Free
  483.   end;
  484. end;
  485. procedure TGUITestRunner.LoadConfiguration;
  486. var
  487.   i :Integer;
  488. begin
  489.   LoadRegistryAction;
  490.   LoadFormPlacement;
  491.   LoadSuiteConfiguration;
  492.   with GetIniFile(IniFileName) do
  493.   try
  494.     with AutoSaveAction do
  495.       Checked := ReadBool(cnConfigIniSection, 'AutoSave', Checked);
  496.     { center splitter location }
  497.     with ResultsPanel do
  498.       Height := ReadInteger(cnConfigIniSection, 'ResultsPanel.Height', Height);
  499.     { error splitter location }
  500.     with ErrorBoxPanel do
  501.       Height := ReadInteger(cnConfigIniSection, 'ErrorMessage.Height', Height);
  502.     with ErrorBoxVisibleAction do
  503.       Checked := ReadBool(cnConfigIniSection, 'ErrorMessage.Visible', Checked);
  504.     ErrorBoxSplitter.Visible := ErrorBoxVisibleAction.Checked;
  505.     ErrorBoxPanel.Visible    := ErrorBoxVisibleAction.Checked;
  506.     { failure list configuration }
  507.     with FailureListView do
  508.     begin
  509.       for i := 0 to Columns.Count-1 do
  510.       begin
  511.         Columns[i].Width := Max(4, ReadInteger(cnConfigIniSection,
  512.                                         Format('FailureList.ColumnWidth[%d]', [i]),
  513.                                         Columns[i].Width)
  514.                                         );
  515.       end;
  516.     end;
  517.     { other options }
  518.     HideTestNodesOnOpenAction.Checked := ReadBool(cnConfigIniSection,
  519.       'HideTestNodesOnOpen', HideTestNodesOnOpenAction.Checked);
  520.     BreakOnFailuresAction.Checked := ReadBool(cnConfigIniSection,
  521.       'BreakOnFailures', BreakOnFailuresAction.Checked);
  522.     ShowTestedNodeAction.Checked := ReadBool(cnConfigIniSection,
  523.       'SelectTestedNode', ShowTestedNodeAction.Checked);
  524.   finally
  525.     Free;
  526.   end;
  527.   if FSuite <> nil then
  528.     UpdateTestTreeState;
  529. end;
  530. procedure TGUITestRunner.AutoSaveConfiguration;
  531. begin
  532.   if AutoSaveAction.Checked then
  533.     SaveConfiguration;
  534. end;
  535. procedure TGUITestRunner.SaveConfiguration;
  536. var
  537.   i :Integer;
  538. begin
  539.   if FSuite <> nil then
  540.     FSuite.SaveConfiguration(IniFileName, UseRegistryAction.Checked, True);
  541.   SaveFormPlacement;
  542.   SaveRegistryAction;
  543.   with GetIniFile(IniFileName) do
  544.   try
  545.    { center splitter location }
  546.    WriteInteger(cnConfigIniSection, 'ResultsPanel.Height',
  547.     ResultsPanel.Height);
  548.    { error box }
  549.    WriteInteger(cnConfigIniSection, 'ErrorMessage.Height',
  550.     ErrorBoxPanel.Height);
  551.    WriteBool(cnConfigIniSection, 'ErrorMessage.Visible',
  552.     ErrorBoxVisibleAction.Checked);
  553.    { failure list configuration }
  554.    with FailureListView do begin
  555.     for i := 0 to Columns.Count-1 do
  556.     begin
  557.      WriteInteger( cnConfigIniSection,
  558.               Format('FailureList.ColumnWidth[%d]', [i]),
  559.               Columns[i].Width);
  560.     end;
  561.    end;
  562.    { other options }
  563.    WriteBool(cnConfigIniSection, 'HideTestNodesOnOpen', HideTestNodesOnOpenAction.Checked);
  564.    WriteBool(cnConfigIniSection, 'BreakOnFailures',     BreakOnFailuresAction.Checked);
  565.    WriteBool(cnConfigIniSection, 'SelectTestedNode',     ShowTestedNodeAction.Checked);
  566.     UpdateFile;
  567.   finally
  568.    Free;
  569.   end;
  570. end;
  571. procedure TGUITestRunner.TestingEnds(testResult :TTestResult);
  572. begin
  573. end;
  574. procedure TGUITestRunner.UpdateNodeState(node: TTreeNode);
  575. var
  576.   test: ITest;
  577. begin
  578.   assert(assigned(node));
  579.   test := NodeToTest(node);
  580.   assert(assigned(test));
  581.   UpdateNodeImage(node);
  582.   if node.HasChildren then
  583.   begin
  584.    node := node.getFirstChild;
  585.    while node <> nil do
  586.    begin
  587.     UpdateNodeState(node);
  588.     node := node.getNextSibling;
  589.    end;
  590.   end;
  591. end;
  592. procedure TGUITestRunner.SetNodeState(node: TTreeNode; enabled :boolean);
  593. var
  594.   MostSeniorChanged :TTReeNode;
  595. begin
  596.   assert(node <> nil);
  597.   // update ancestors if enabling
  598.   NodeToTest(Node).Enabled := enabled;
  599.   MostSeniorChanged := Node;
  600.   if enabled then
  601.   begin
  602.     while Node.Parent <> nil do
  603.     begin
  604.      Node := Node.Parent;
  605.      if not NodeToTest(Node).Enabled then
  606.      begin // changed
  607.        NodeToTest(Node).Enabled := true;
  608.        MostSeniorChanged := Node;
  609.        UpdateNodeImage(Node);
  610.      end
  611.     end;
  612.   end;
  613.   TestTree.Items.BeginUpdate;
  614.   try
  615.     UpdateNodeState(MostSeniorChanged);
  616.   finally
  617.     TestTree.Items.EndUpdate;
  618.   end
  619. end;
  620. procedure TGUITestRunner.SwitchNodeState(node: TTreeNode);
  621. begin
  622.   assert(node <> nil);
  623.   SetNodeState(node, not NodeToTest(node).enabled);
  624. end;
  625. procedure TGUITestRunner.UpdateTestTreeState;
  626. var
  627.   node :TTreeNode;
  628. begin
  629.   if TestTree.Items.Count > 0 then
  630.   begin
  631.    TestTree.Items.BeginUpdate;
  632.    try
  633.     node := TestTree.Items.GetFirstNode;
  634.     while node <> nil do
  635.     begin
  636.       UpdateNodeState(node);
  637.       node := node.getNextSibling;
  638.     end
  639.    finally
  640.     TestTree.Items.EndUpdate;
  641.    end;
  642.   end;
  643. end;
  644. procedure TGUITestRunner.UpdateStatus(const fullUpdate:Boolean);
  645. var
  646.   i :Integer;
  647.   TestNumber: Integer;
  648. function FormatElapsedTime(milli: Int64):string;
  649.   var
  650.     h,nn,ss,zzz: Cardinal;
  651.   begin
  652.     h := milli div 3600000;
  653.     milli := milli mod 3600000;
  654.     nn := milli div 60000;
  655.     milli := milli mod 60000;
  656.     ss := milli div 1000;
  657.     milli := milli mod 1000;
  658.     zzz := milli;
  659.     Result := Format('%d:%2.2d:%2.2d.%3.3d', [h, nn, ss, zzz]);
  660.   end;
  661. begin
  662.   if fullUpdate then
  663.    if FSuite <> nil then
  664.     ResultsView.Items[0].SubItems[0] := IntToStr(FSuite.countEnabledTestCases)
  665.    else
  666.     ResultsView.Items[0].SubItems[0] := '';
  667.   if testResult <> nil then
  668.   begin
  669.    // Save the test number as we use it a lot
  670.    TestNumber := TestResult.runCount;
  671.    // Only update every 8 tests to speed things up considerably
  672.    if fullUpdate or ((TestNumber and 7) = 0) then
  673.    begin
  674.     with ResultsView.Items[0] do
  675.     begin
  676.      SubItems[1] := IntToStr(TestNumber);
  677.      SubItems[2] := IntToStr(testResult.failureCount);
  678.      SubItems[3] := IntToStr(testResult.errorCount);
  679.      SubItems[4] := FormatElapsedTime(testResult.TotalTime);
  680.     end;
  681.     with testResult do
  682.     begin
  683.      ScoreBar.Position  := TestNumber - (failureCount + errorCount);
  684.      ProgressBar.Position := TestNumber;
  685.      // There is a possibility for zero tests
  686.      if (TestNumber = 0) and (Suite.CountEnabledTestCases = 0) then
  687.       LbProgress.Caption := '100%'
  688.      else
  689.       LbProgress.Caption := IntToStr((100 * ScoreBar.Position) div ScoreBar.Max) + '%';
  690.     end;
  691.     // Allow the display to catch up and check for key strokes
  692.     Application.ProcessMessages;
  693.    end;
  694.   end
  695.   else
  696.   begin
  697.    with ResultsView.Items[0] do
  698.    begin
  699.     for i := 1 to 4 do
  700.       SubItems[i] := ''
  701.    end;
  702.    ResetProgress;
  703.   end;
  704.   if fullUpdate then
  705.     Update;
  706. end;
  707. procedure TGUITestRunner.ResetProgress;
  708. begin
  709.   TProgressBarCrack(ScoreBar).ParentColor := True;
  710.   ScoreBar.Position := 0;
  711.   ProgressBar.Position := 0;
  712.   LbProgress.Caption := '';
  713. end;
  714. function TGUITestRunner.AddFailureItem(failure: TTestFailure): TListItem;
  715. var
  716.   item : TListItem;
  717.   node : TTreeNode;
  718. begin
  719.   assert(assigned(failure));
  720.   item := FailureListView.Items.Add;
  721.   item.data := Pointer(TestToNode(failure.failedTest));
  722.   item.Caption := failure.failedTest.Name;
  723.   item.SubItems.Add(failure.thrownExceptionName);
  724.   item.SubItems.Add(failure.thrownExceptionMessage);
  725.   item.SubItems.Add( PointerToLocationInfo(failure.ThrownExceptionAddress)
  726.               + ' ' +
  727.               PointerToAddressInfo(failure.ThrownExceptionAddress)
  728.               );
  729.               
  730.   node := testToNode(failure.failedTest);
  731.   while node <> nil do
  732.   begin
  733.    node.Expand(false);
  734.    node := node.Parent;
  735.   end;
  736.   Result := item;
  737. end;
  738. procedure TGUITestRunner.FillTestTree(RootNode: TTreeNode; ATest: ITest);
  739. var
  740.   Tests: IInterfaceList;
  741.   i:     Integer;
  742.   index: Integer;
  743. begin
  744.   if ATest = nil then
  745.    EXIT;
  746.   RootNode := TestTree.Items.AddChild(RootNode, ATest.Name);
  747.   index := FTests.Add(ATest);
  748.   RootNode.data := Pointer(index);
  749.   Tests := ATest.Tests;
  750.   for i := 0 to Tests.count - 1 do
  751.   begin
  752.    FillTestTree(RootNode, Tests[i] as ITest);
  753.   end;
  754. end;
  755. procedure TGUITestRunner.FillTestTree(ATest: ITest);
  756. begin
  757.   TestTree.Items.Clear;
  758.   FTests.Clear;
  759.   fillTestTree(nil, FSuite);
  760. end;
  761. procedure TGUITestRunner.SetTreeNodeImage(Node :TTReeNode; imgIndex :Integer);
  762. begin
  763.   while Node <> nil do
  764.   begin
  765.    if imgIndex > Node.ImageIndex then
  766.    begin
  767.      Node.ImageIndex    := imgIndex;
  768.      Node.SelectedIndex := imgIndex;
  769.    end;
  770.    if imgIndex = imgRunning then
  771.     Node := nil
  772.    else
  773.     Node := Node.Parent;
  774.   end;
  775. end;
  776. procedure TGUITestRunner.SetSuite(value: ITest);
  777. begin
  778.   FSuite := value;
  779.   LoadSuiteConfiguration;
  780.   EnableUI(FSuite <> nil);
  781.   if (FSuite <> nil) then InitTree;
  782. end;
  783. procedure TGUITestRunner.DisplayFailureMessage(Item: TListItem);
  784. begin
  785. //  the followinf line has been moved
  786. //  TestTree.Selected := TTreeNode(Item.data);
  787.   TestNameLabel.Caption  := Item.Caption + ':  ';
  788.   ErrorTypeLabel.Caption := Item.SubItems[0] + ' at ' + Item.SubItems[2];
  789.   MessageLabel.Caption   := Item.SubItems[1];
  790.   if Item.ImageIndex >= imgERROR then
  791.      ErrorTypeLabel.Font.Color := clERROR
  792.   else
  793.      ErrorTypeLabel.Font.Color := clFAILURE;
  794. end;
  795. procedure TGUITestRunner.ClearFailureMessage;
  796. begin
  797.   if assigned(ErrorBoxPanel) then
  798.   begin
  799.   TestNameLabel.Caption  := '';
  800.   ErrorTypeLabel.Caption := '';
  801.   MessageLabel.Caption   := '';
  802.   end;
  803. end;
  804. procedure TGUITestRunner.ClearResult;
  805. begin
  806.   if FTestResult <> nil then
  807.   begin
  808.    FTestResult.Free;
  809.    FTestResult := nil;
  810.    ClearFailureMessage;
  811.   end;
  812. end;
  813. procedure TGUITestRunner.SetUp;
  814. var
  815.   i: Integer;
  816.   node: TTreeNode;
  817. begin
  818.   FailureListView.Items.Clear;
  819.   ResetProgress;
  820.   Update;
  821.   with ResultsView.Items[0] do
  822.   begin
  823.    if FSuite <> nil then
  824.    begin
  825.     SubItems[0] := IntToStr(FSuite.countEnabledTestCases);
  826.    end
  827.    else
  828.    begin
  829.     SubItems[0] := '';
  830.    end;
  831.    SubItems[1] := '';
  832.    SubItems[2] := '';
  833.    SubItems[3] := '';
  834.    SubItems[4] := '';
  835.   end;
  836.   if FSuite <> nil then
  837.   begin
  838.    ProgressBar.Max := FSuite.countEnabledTestCases;
  839.   end
  840.   else
  841.   begin
  842.    ProgressBar.Max:= 10000;
  843.   end;
  844.   ScoreBar.Max := ProgressBar.Max;
  845.   for i := 0 to TestTree.Items.Count - 1 do
  846.   begin
  847.    node := TestTree.Items[i];
  848.    node.ImageIndex    := imgNONE;
  849.    node.SelectedIndex := imgNONE;
  850.   end;
  851.   UpdateTestTreeState;
  852. end;
  853. procedure TGUITestRunner.EnableUI(enable: Boolean);
  854. begin
  855.   SelectAllAction.Enabled    := enable;
  856.   DeselectAllAction.Enabled  := enable;
  857.   SelectFailedAction.Enabled := enable;
  858.   SelectCurrentAction.Enabled := enable;
  859.   DeselectCurrentAction.Enabled := enable;
  860.   HideTestNodesAction.Enabled   := enable;
  861.   ExpandAllNodesAction.Enabled  := enable;
  862. end;
  863. procedure TGUITestRunner.RunTheTest(aTest : ITest);
  864. begin
  865.   if aTest = nil then
  866.     EXIT;
  867.   if FRunning then begin
  868.     // warning: we're reentering this method if FRunning is true
  869.     assert(FTestResult <> nil);
  870.     FTestResult.Stop;
  871.     EXIT;
  872.   end;
  873.   FRunning := true;
  874.   try
  875.     RunAction.Enabled  := False;
  876.     StopAction.Enabled := True;
  877.     CopyMessageToClipboardAction.Enabled := false;
  878.     EnableUI(false);
  879.     AutoSaveConfiguration;
  880.     ClearResult;
  881.     TestResult := TTestResult.create;
  882.     try
  883.       testResult.addListener(self);
  884.       testResult.BreakOnFailures := BreakOnFailuresAction.Checked;
  885.       aTest.run(testResult);
  886.     finally
  887.       testResult.Free;
  888.       testResult := nil;
  889.     end;
  890.   finally
  891.       FRunning := false;
  892.       EnableUI(true);
  893.   end;
  894. end;
  895. procedure TGUITestRunner.FormCreate(Sender: TObject);
  896. begin
  897.   inherited;
  898.   FTests := TInterfaceList.Create;
  899.   LoadConfiguration;
  900.   TimeSeparator := ':';
  901.   SetUpStateImages;
  902.   TestTree.Items.Clear;
  903.   EnableUI(false);
  904.   ClearFailureMessage;
  905.   Setup;
  906. end;
  907. procedure TGUITestRunner.FormDestroy(Sender: TObject);
  908. begin
  909.   ClearResult;
  910.   AutoSaveConfiguration;
  911.   Suite := nil;
  912.   FTests.Free;
  913.   inherited;
  914. end;
  915. procedure TGUITestRunner.FormShow(Sender: TObject);
  916. var
  917.   node: TTreeNode;
  918.   test: ITest;
  919. begin
  920.   // Set up the GUI nodes here to be the same as GUITestRunner.pas
  921.   node := TestTree.Items.GetFirstNode;
  922.   while assigned(node) do
  923.   begin
  924.     // Get and check the test for the tree node
  925.     test := NodeToTest(node);
  926.     assert(Assigned(test));
  927.     // Save the tree node in the test and get the next tree node
  928.     test.GUIObject := node;
  929.     node := node.GetNext;
  930.   end;
  931. end;
  932. procedure TGUITestRunner.TestTreeClick(Sender: TObject);
  933. begin
  934.   if FRunning then
  935.     Exit;
  936.   ProcessClickOnStateIcon;
  937.   TestTreeChange(Sender, TestTree.Selected);
  938. end;
  939. procedure TGUITestRunner.TestTreeChange(Sender: TObject; Node: TTreeNode);
  940. var
  941.   i : Integer;
  942.   SelectedFailure: TListItem;
  943. begin
  944.   if (Node <> nil) and (Node = TestTree.Selected) then
  945.   begin
  946.     SelectedFailure := nil;
  947.     for i := 0 to FailureListView.Items.count - 1 do
  948.     begin
  949.       if TTreeNode(FailureListView.Items[i].Data) = Node then
  950.       begin
  951.         SelectedFailure := FailureListView.Items[i];
  952.         break;
  953.       end;
  954.     end;
  955.     FailureListView.Selected := SelectedFailure;
  956. {$IF RTLVersion < 14.1}
  957.   // workaround for a bug in early CLX
  958.   // not allowing to set SelectedItem property to nil
  959.   if not Assigned(SelectedFailure) then
  960.     ClearFailureMessage
  961.   else
  962.     DisplayFailureMessage(SelectedFailure);
  963. {$IFEND}
  964.     UpdateStatus(True);
  965.   end;
  966. end;
  967. procedure TGUITestRunner.FailureListViewClick(Sender: TObject);
  968. begin
  969.   if FailureListView.Selected <> nil then
  970.   begin
  971.     TestTree.Selected := TTreeNode(FailureListView.Selected.data);
  972.   end;
  973. end;
  974. procedure TGUITestRunner.FailureListViewSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
  975. begin
  976.   if not Selected then
  977.     ClearFailureMessage
  978.   else
  979.     DisplayFailureMessage(Item);
  980. end;
  981. function TGUITestRunner.DisableTest(test: ITest): boolean;
  982. begin
  983.   test.enabled := false;
  984.   result := true;
  985. end;
  986. function TGUITestRunner.EnableTest(test: ITest): boolean;
  987. begin
  988.   test.enabled := true;
  989.   result := true;
  990. end;
  991. procedure TGUITestRunner.ApplyToTests(root :TTreeNode; const func :TTestFunc);
  992.   procedure DoApply(root :TTreeNode);
  993.   var
  994.    test: ITest;
  995.    node: TTreeNode;
  996.   begin
  997.    if root <> nil then
  998.    begin
  999.     test := NodeToTest(root);
  1000.     if func(test) then
  1001.     begin
  1002.       node := root.getFirstChild;
  1003.       while node <> nil do
  1004.       begin
  1005.        DoApply(node);
  1006.        node := node.getNextSibling;
  1007.       end;
  1008.     end;
  1009.    end;
  1010.   end;
  1011. begin
  1012.   TestTree.Items.BeginUpdate;
  1013.   try
  1014.    DoApply(root)
  1015.   finally
  1016.    TestTree.Items.EndUpdate
  1017.   end;
  1018.   UpdateTestTreeState;
  1019. end;
  1020. procedure TGUITestRunner.TestTreeKeyPress(Sender: TObject; var Key: Char);
  1021. begin
  1022.   if (Key = ' ') and (TestTree.Selected <> nil) then
  1023.   begin
  1024.    SwitchNodeState(TestTree.Selected);
  1025.    UpdateStatus(True);
  1026.    Key := #0
  1027.   end;
  1028. end;
  1029. procedure TGUITestRunner.SelectAllActionExecute(Sender: TObject);
  1030. begin
  1031.   ApplyToTests(TestTree.Items.GetFirstNode, EnableTest);
  1032.   UpdateStatus(True);
  1033. end;
  1034. procedure TGUITestRunner.DeselectAllActionExecute(Sender: TObject);
  1035. begin
  1036.   ApplyToTests(TestTree.Items.GetFirstNode, DisableTest);
  1037.   UpdateStatus(True);
  1038. end;
  1039. procedure TGUITestRunner.SelectFailedActionExecute(Sender: TObject);
  1040. var
  1041.   i: integer;
  1042.   ANode: TTreeNode;
  1043. begin
  1044.   { deselect all }
  1045.   ApplyToTests(TestTree.Items[0], DisableTest);
  1046.   { select failed }
  1047.   for i := 0 to FailureListView.Items.Count - 1 do
  1048.   begin
  1049.    ANode := TTreeNode(FailureListView.Items[i].Data);
  1050.    SetNodeState(ANode, true);
  1051.   end;
  1052.   UpdateStatus(True);
  1053. end;
  1054. procedure TGUITestRunner.SaveConfigurationActionExecute(Sender: TObject);
  1055. begin
  1056.   SaveConfiguration
  1057. end;
  1058. procedure TGUITestRunner.RestoreSavedActionExecute(Sender: TObject);
  1059. begin
  1060.   LoadConfiguration
  1061. end;
  1062. procedure TGUITestRunner.AutoSaveActionExecute(Sender: TObject);
  1063. begin
  1064.   with AutoSaveAction do
  1065.   begin
  1066.    Checked := not Checked
  1067.   end;
  1068.   AutoSaveConfiguration;
  1069. end;
  1070. procedure TGUITestRunner.ErrorBoxVisibleActionExecute(Sender: TObject);
  1071. begin
  1072.   with ErrorBoxVisibleAction do
  1073.   begin
  1074.     Checked := not Checked;
  1075.     ErrorBoxSplitter.Visible := Checked;
  1076.     ErrorBoxPanel.Visible    := Checked;
  1077.     if Checked then
  1078.     begin
  1079.     // Solve bugs with Delphi4 resizing with constraints
  1080.      ErrorBoxSplitter.Top := ErrorBoxPanel.Top-8;
  1081.     end
  1082.   end;
  1083. end;
  1084. procedure TGUITestRunner.ErrorBoxSplitterMoved(Sender: TObject);
  1085. begin
  1086.   // Solve bugs with Delphi4 resizing with constraints
  1087.   ErrorBoxSplitter.Top := ErrorBoxPanel.Top-8;
  1088.   self.Update;
  1089. end;
  1090. procedure TGUITestRunner.ErrorBoxPanelResize(Sender: TObject);
  1091. begin
  1092.   // Solve bugs with Delphi4 resizing with constraints
  1093.   ErrorBoxSplitter.Top := ErrorBoxPanel.Top-8;
  1094. end;
  1095. function TGUITestRunner.NodeIsGrandparent(ANode: TTreeNode): boolean;
  1096. var
  1097.   AChildNode: TTreeNode;
  1098. begin
  1099.   Result := false;
  1100.   if ANode.HasChildren then
  1101.   begin
  1102.    AChildNode := ANode.GetFirstChild;
  1103.    while AChildNode <> nil do
  1104.    begin
  1105.     Result := AChildNode.HasChildren or Result;
  1106.     AChildNode := ANode.GetNextChild(AChildNode);
  1107.    end;
  1108.   end;
  1109. end;
  1110. procedure TGUITestRunner.CollapseNonGrandparentNodes(RootNode: TTreeNode);
  1111. var
  1112.   AChildNode: TTreeNode;
  1113. begin
  1114.   if not NodeIsGrandparent(RootNode) then
  1115.    RootNode.Collapse(false);
  1116.   AChildNode := RootNode.GetFirstChild;
  1117.   while AChildNode <> nil do
  1118.   begin
  1119.    CollapseNonGrandparentNodes(AChildNode);
  1120.    AChildNode := RootNode.GetNextChild(AChildNode);
  1121.   end;
  1122. end;
  1123. procedure TGUITestRunner.HideTestNodesActionExecute(Sender: TObject);
  1124. var
  1125.   ANode: TTreeNode;
  1126. begin
  1127.   inherited;
  1128.   if TestTree.Items.Count = 0 then
  1129.    EXIT;
  1130.    
  1131.   TestTree.Items.BeginUpdate;
  1132.   try
  1133.    ANode := TestTree.Items[0];
  1134.    if ANode <> nil then
  1135.    begin
  1136.     ANode.Expand(true);
  1137.     CollapseNonGrandparentNodes(ANode);
  1138.     ANode.Selected := true;
  1139.     MakeNodeVisible(ANode);
  1140.    end;
  1141.   finally
  1142.    TestTree.Items.EndUpdate;
  1143.   end;
  1144. end;
  1145. procedure TGUITestRunner.HideTestNodesOnOpenActionExecute(Sender: TObject);
  1146. begin
  1147.   HideTestNodesOnOpenAction.Checked := not HideTestNodesOnOpenAction.Checked;
  1148. end;
  1149. procedure TGUITestRunner.ExpandAllNodesActionExecute(Sender: TObject);
  1150. begin
  1151.   TestTree.FullExpand;
  1152.   if (TestTree.Selected <> nil) then
  1153.    MakeNodeVisible(TestTree.Selected)
  1154.   else if(TestTree.Items.Count > 0) then
  1155.    TestTree.Selected := TestTree.Items[0];
  1156. end;
  1157. procedure TGUITestRunner.RunActionExecute(Sender: TObject);
  1158. begin
  1159.   if FSuite = nil then
  1160.    EXIT;
  1161.   if FRunning then begin
  1162.    // warning: we're reentering this method if FRunning is true
  1163.    assert(FTestResult <> nil);
  1164.    FTestResult.Stop;
  1165.    EXIT;
  1166.   end;
  1167.   RunAction.Enabled  := False;
  1168.   StopAction.Enabled := True;
  1169.   
  1170.   CopyMessageToClipboardAction.Enabled := false;
  1171.   EnableUI(false);
  1172.   FRunning := true;
  1173.   try
  1174.    Setup;
  1175.    AutoSaveConfiguration;
  1176.    ClearResult;
  1177.    TestResult := TTestResult.create;
  1178.    try
  1179.     testResult.addListener(self);
  1180.     testResult.BreakOnFailures := BreakOnFailuresAction.Checked;
  1181.     suite.run(testResult);
  1182.    finally
  1183.     testResult.Free;
  1184.     testResult := nil;
  1185.    end;
  1186.   finally
  1187.     FRunning := false;
  1188.     EnableUI(true);
  1189.   end;
  1190. end;
  1191. procedure TGUITestRunner.ExitActionExecute(Sender: TObject);
  1192. begin
  1193.   if FTestResult <> nil then
  1194.     FTestResult.stop;
  1195.   self.ModalResult := mrCancel;
  1196.   Close;
  1197. end;
  1198. procedure TGUITestRunner.BreakOnFailuresActionExecute(Sender: TObject);
  1199. begin
  1200.   with BreakOnFailuresAction do
  1201.   Checked := not Checked;
  1202. end;
  1203. procedure TGUITestRunner.ShowTestedNodeActionExecute(Sender: TObject);
  1204. begin
  1205.   with ShowTestedNodeAction do
  1206.    Checked := not Checked;
  1207. end;
  1208. procedure TGUITestRunner.SetUpStateImages;
  1209. begin
  1210.   TestTree.Images             := RunImages;
  1211. end;
  1212. procedure TGUITestRunner.LoadSuiteConfiguration;
  1213. begin
  1214.   if FSuite <> nil then
  1215.    FSuite.LoadConfiguration(IniFileName, UseRegistryAction.Checked, True);
  1216. end;
  1217. procedure TGUITestRunner.MakeNodeVisible(node: TTreeNode);
  1218. begin
  1219.   {$IF RTLVersion >= 14.5}
  1220.   node.MakeVisible;
  1221.   {$ELSE}
  1222.   node.MakeVisible(true);
  1223.   {$IFEND}
  1224. end;
  1225. procedure TGUITestRunner.ProcessClickOnStateIcon;
  1226. const
  1227.   APROX_IMAGE_WIDTH = 40;
  1228. var
  1229.   Node: TTreeNode;
  1230.   Pos: TPoint;
  1231.   Rect: TRect;
  1232. begin
  1233.   GetCursorPos(Pos);
  1234.   Pos := TestTree.ScreenToClient(Pos);
  1235.   Node := TestTree.GetNodeAt(Pos.X, Pos.Y);
  1236.   if Assigned(Node) then
  1237.   begin
  1238.     Rect := Node.DisplayRect;
  1239.     if Pos.X < (Node.Level * TestTree.Indent + APROX_IMAGE_WIDTH) then
  1240.       SwitchNodeState(node);
  1241.   end;
  1242. end;
  1243. procedure TGUITestRunner.UpdateNodeImage(node: TTreeNode);
  1244. var
  1245.   test :ITest;
  1246. begin
  1247.   test := NodeToTest(node);
  1248.   if Test.Enabled then
  1249.     Node.ImageIndex := CalcImageIndex(0, NodeRunImageIndex(Node))
  1250.   else
  1251.     Node.ImageIndex := CalcImageIndex(1, NodeRunImageIndex(Node));
  1252. {  if not test.enabled then
  1253.   begin
  1254.     node.StateIndex := imgDISABLED;
  1255.   end
  1256.   else if (node.Parent <> nil)
  1257.   and (node.Parent.StateIndex <= imgPARENT_DISABLED) then
  1258.   begin
  1259.     node.StateIndex := imgPARENT_DISABLED;
  1260.   end
  1261.   else
  1262.   begin
  1263.     node.StateIndex := imgENABLED;
  1264.   end; }
  1265. end;
  1266. procedure TGUITestRunner.UseRegistryActionExecute(Sender: TObject);
  1267. begin
  1268.   with UseRegistryAction do
  1269.    Checked := not Checked;
  1270. end;
  1271. function TGUITestRunner.GetIniFile(const FileName: string) : tCustomIniFile;
  1272. begin
  1273.   Result := TIniFile.Create( FileName );
  1274. end;
  1275. procedure TGUITestRunner.LoadRegistryAction;
  1276. begin
  1277.   with TIniFile.Create(IniFileName) do
  1278.   try
  1279.    UseRegistryAction.Checked := ReadBool(cnConfigIniSection,
  1280.     'UseRegistry', UseRegistryAction.Checked);
  1281.   finally
  1282.    Free;
  1283.   end;
  1284. end;
  1285. procedure TGUITestRunner.SaveRegistryAction;
  1286. begin
  1287.   if UseRegistryAction.Checked then
  1288.    DeleteFile( IniFileName );
  1289.   with TIniFile.Create(IniFileName) do
  1290.   try
  1291.    WriteBool(cnConfigIniSection, 'UseRegistry', UseRegistryAction.Checked);
  1292.   finally
  1293.    Free;
  1294.   end;
  1295. end;
  1296. procedure TGUITestRunner.RunActionUpdate(Sender: TObject);
  1297. begin
  1298.   RunAction.Enabled := not FRunning and assigned( fSuite ) and (FSuite.countEnabledTestCases > 0);
  1299. end;
  1300. procedure TGUITestRunner.CopyMessageToClipboardActionUpdate(Sender: TObject);
  1301. begin
  1302.   CopyMessageToClipboardAction.Enabled := FailureListView.Selected <> nil;
  1303. end;
  1304. procedure TGUITestRunner.SelectCurrentActionExecute(Sender: TObject);
  1305. begin
  1306.   ApplyToTests(TestTree.Selected, EnableTest);
  1307.   SetNodeState(TestTree.Selected, true);
  1308.   UpdateStatus(True);
  1309. end;
  1310. procedure TGUITestRunner.DeselectCurrentActionExecute(Sender: TObject);
  1311. begin
  1312.   ApplyToTests(TestTree.Selected, DisableTest);
  1313.   UpdateStatus(True);
  1314. end;
  1315. procedure TGUITestRunner.StopActionExecute(Sender: TObject);
  1316. begin
  1317.   if FTestResult <> nil then
  1318.     FTestResult.stop;
  1319. end;
  1320. procedure TGUITestRunner.StopActionUpdate(Sender: TObject);
  1321. begin
  1322.   StopAction.Enabled := FRunning and (FTestResult <> nil);
  1323. end;
  1324. procedure TGUITestRunner.Status(test: ITest; const Msg: string);
  1325. begin
  1326.   // Empty stub for now
  1327. end;
  1328. procedure TGUITestRunner.Warning(test: ITest; const Msg: string);
  1329. begin
  1330.   // Empty stub for now
  1331. end;
  1332. procedure TGUITestRunner.RunSelectedTestActionExecute(Sender: TObject);
  1333. begin
  1334.   Setup;
  1335.   ListSelectedTests;
  1336.   ProgressBar.Max := 1;
  1337.   ScoreBar.Max    := 1;
  1338.   RunTheTest(Suite);
  1339.   FreeAndNil(FSelectedTests);
  1340. end;
  1341. procedure TGUITestRunner.RunSelectedTestActionUpdate(Sender: TObject);
  1342. var
  1343.   aTest :ITest;
  1344. begin
  1345.   ATest := SelectedTest;
  1346.   RunSelectedTestAction.Enabled := (aTest <> nil) and (aTest.CountTestCases = 1);
  1347. end;
  1348. end.