Project

General

Profile

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
function TestLoop(commandFactory) {
18
    this.commandFactory = commandFactory;
19
}
20

    
21
TestLoop.prototype = {
22

    
23
    start : function() {
24
        selenium.reset();
25
        LOG.debug("currentTest.start()");
26
        this.continueTest();
27
    },
28

    
29
    continueTest : function() {
30
        /**
31
         * Select the next command and continue the test.
32
         */
33
        LOG.debug("currentTest.continueTest() - acquire the next command");
34
        if (! this.aborted) {
35
            this.currentCommand = this.nextCommand();
36
        }
37
        if (! this.requiresCallBack) {
38
            this.continueTestAtCurrentCommand();
39
        } // otherwise, just finish and let the callback invoke continueTestAtCurrentCommand()
40
    },
41

    
42
    continueTestAtCurrentCommand : function() {
43
        LOG.debug("currentTest.continueTestAtCurrentCommand()");
44
        if (this.currentCommand) {
45
            // TODO: rename commandStarted to commandSelected, OR roll it into nextCommand
46
            this.commandStarted(this.currentCommand);
47
            this._resumeAfterDelay();
48
        } else {
49
            this._testComplete();
50
        }
51
    },
52

    
53
    _resumeAfterDelay : function() {
54
        /**
55
         * Pause, then execute the current command.
56
         */
57

    
58
        // Get the command delay. If a pauseInterval is set, use it once
59
        // and reset it.  Otherwise, use the defined command-interval.
60
        var delay = this.pauseInterval || this.getCommandInterval();
61
        this.pauseInterval = undefined;
62

    
63
        if (this.currentCommand.isBreakpoint || delay < 0) {
64
            // Pause: enable the "next/continue" button
65
            this.pause();
66
        } else {
67
            window.setTimeout(fnBind(this.resume, this), delay);
68
        }
69
    },
70

    
71
    resume: function() {
72
        /**
73
         * Select the next command and continue the test.
74
         */
75
        LOG.debug("currentTest.resume() - actually execute");
76
        try {
77
            selenium.browserbot.runScheduledPollers();
78
            this._executeCurrentCommand();
79
            this.continueTestWhenConditionIsTrue();
80
        } catch (e) {
81
            if (!this._handleCommandError(e)) {
82
                this._testComplete();
83
            } else {
84
                this.continueTest();
85
            }
86
        }
87
    },
88

    
89
    _testComplete : function() {
90
        selenium.ensureNoUnhandledPopups();
91
        this.testComplete();
92
    },
93

    
94
    _executeCurrentCommand : function() {
95
        /**
96
         * Execute the current command.
97
         *
98
         * @return a function which will be used to determine when
99
         * execution can continue, or null if we can continue immediately
100
         */
101
        var command = this.currentCommand;
102
        LOG.info("Executing: |" + command.command + " | " + command.target + " | " + command.value + " |");
103

    
104
        var handler = this.commandFactory.getCommandHandler(command.command);
105
        if (handler == null) {
106
            throw new SeleniumError("Unknown command: '" + command.command + "'");
107
        }
108

    
109
        command.target = selenium.preprocessParameter(command.target);
110
        command.value = selenium.preprocessParameter(command.value);
111
        LOG.debug("Command found, going to execute " + command.command);
112
        this.result = handler.execute(selenium, command);
113
        
114

    
115
        this.waitForCondition = this.result.terminationCondition;
116

    
117
    },
118

    
119
    _handleCommandError : function(e) {
120
        if (!e.isSeleniumError) {
121
            LOG.exception(e);
122
            var msg = "Selenium failure. Please report to selenium-dev@openqa.org, with error details from the log window.";
123
            if (e.message) {
124
                msg += "  The error message is: " + e.message;
125
            }
126
            return this.commandError(msg);
127
        } else {
128
            LOG.error(e.message);
129
            return this.commandError(e.message);
130
        }
131
    },
132

    
133
    continueTestWhenConditionIsTrue: function () {
134
        /**
135
         * Busy wait for waitForCondition() to become true, and then carry
136
         * on with test.  Fail the current test if there's a timeout or an
137
         * exception.
138
         */
139
        //LOG.debug("currentTest.continueTestWhenConditionIsTrue()");
140
        selenium.browserbot.runScheduledPollers();
141
        try {
142
            if (this.waitForCondition == null) {
143
                LOG.debug("null condition; let's continueTest()");
144
                LOG.debug("Command complete");
145
                this.commandComplete(this.result);
146
                this.continueTest();
147
            } else if (this.waitForCondition()) {
148
                LOG.debug("condition satisfied; let's continueTest()");
149
                this.waitForCondition = null;
150
                LOG.debug("Command complete");
151
                this.commandComplete(this.result);
152
                this.continueTest();
153
            } else {
154
                //LOG.debug("waitForCondition was false; keep waiting!");
155
                window.setTimeout(fnBind(this.continueTestWhenConditionIsTrue, this), 10);
156
            }
157
        } catch (e) {
158
            this.result = {};
159
            this.result.failed = true;
160
            this.result.failureMessage = extractExceptionMessage(e);
161
            this.commandComplete(this.result);
162
            this.continueTest();
163
        }
164
    },
165

    
166
    pause : function() {},
167
    nextCommand : function() {},
168
    commandStarted : function() {},
169
    commandComplete : function() {},
170
    commandError : function() {},
171
    testComplete : function() {},
172

    
173
    getCommandInterval : function() {
174
        return 0;
175
    }
176

    
177
}
(14-14/20)