public void ExceptionIsThrownIfCallingAddCleanupActionFromWithinACleaupAction()
        {
            var context = new TestExecutionScopesManager("dummy", ctx => { });

            context.AddCleanupAction(() =>
            {
                context.AddCleanupAction(() => { Assert.Fail("This code should never be called!"); });
            });

            TestUtils.ExpectException <InvalidOperationException>(() =>
            {
                context.EndIsolationScope();
            });
        }
Example #2
0
        /// <summary>
        /// Invokes a delegate that causes a new window to open, and return an object representing the new window
        /// </summary>
        /// <param name="action">The delegate that should cause a new window to open</param>
        /// <param name="windowDescription">A description that will identify the window in the log</param>
        /// <param name="timeout">The maximal time to wait for the window to open</param>
        /// <returns>The <see cref="BrowserWindow"/> object that represent the newly opened window</returns>
        /// <exception cref="ArgumentNullException"><paramref name="action"/> or <paramref name="windowDescription"/> are null</exception>
        /// <exception cref="TimeoutException">A new window wasn't opened for the specified timeout after the delegate completed</exception>
        /// <remarks>
        /// When the current <see cref="IIsolationScope"/> ends, the window is automatically closed
        /// </remarks>
        /// <example>
        /// <code>
        /// var openNewWindowButton = myBrowser.WaitForElement(By.Id("openNewWindowButtonId"), "Open new window button");
        /// var newWindow = myBrowser.OpenWindow(() => openNewButton.Click(), "New window");
        /// Assert.AreEqual("New window Title", newWindow.Title);
        /// </code>
        /// </example>
        public BrowserWindow OpenWindow([InstantHandle] Action action, string windowDescription, TimeSpan timeout)
        {
            CheckDisposed();
            if (action == null)
            {
                throw new ArgumentNullException("action");
            }
            if (windowDescription == null)
            {
                throw new ArgumentNullException("windowDescription");
            }
            Activate();
            var webDriver       = GetWebDriver();
            var existingHandles = webDriver.WindowHandles;

            action();

            var newWindowHandle = Wait.Until(() => webDriver.WindowHandles.Except(existingHandles).SingleOrDefault(),
                                             handle => handle != null,
                                             timeout, "Window '{0}' wasn't opened for 60 seconds", windowDescription);

            Logger.WriteLine("Opened window '{0}' with id={1} ({2})", windowDescription, newWindowHandle.GetHashCode(), newWindowHandle);

            var newWindow = new BrowserWindow(this, newWindowHandle, windowDescription);

            _testExecutionScopesManager.AddCleanupAction(() => newWindow.Close());

            return(newWindow);
        }
        public void DoesNothingIfInitializeIsNull()
        {
            bool outerCleanupIsCalled = false, innerCleanupIsCalled = false;

            Action <IIsolationScope> nullInitialize = null;

            var context = new TestExecutionScopesManager("OuterScope", nullInitialize);

            context.AddCleanupAction(() => outerCleanupIsCalled = true);

            context.BeginIsolationScope("InnerScope", nullInitialize);
            context.AddCleanupAction(() => innerCleanupIsCalled = true);

            context.EndIsolationScope();
            Assert.IsTrue(innerCleanupIsCalled);
            context.EndIsolationScope();
            Assert.IsTrue(outerCleanupIsCalled);
        }
        public void CleaupActionIsCalledAfterInitialize()
        {
            bool cleanupWasCalled = false;
            var  context          = new TestExecutionScopesManager("dummy", ctx => { });

            context.AddCleanupAction(() => cleanupWasCalled = true);

            context.EndIsolationScope();
            Assert.IsTrue(cleanupWasCalled);
        }
        public void StackTraceOfCleanupActionContainsTheOriginalLineItWasThrown()
        {
            var manager = new TestExecutionScopesManager("dummy", Functions.EmptyAction <IIsolationScope>());

            manager.AddCleanupAction(MethodThatThrowsException);

            var ex = TestUtils.ExpectException <Exception>(manager.EndIsolationScope);

            StringAssert.Contains(ex.StackTrace, "MethodThatThrowsException");
        }
        public void ExceptionInNestedLevelInitialization()
        {
            var calledActions = new List <string>();
            var context       = new TestExecutionScopesManager("dummy", ctx => { });

            context.AddCleanupAction(() => calledActions.Add("action1"));

            var ex = TestUtils.ExpectException <Exception>(() => context.BeginIsolationScope("nested", ctx =>
            {
                context.AddCleanupAction(() => calledActions.Add("action2"));
                throw new Exception("DummyExceptionMessage");
            }));

            Assert.AreEqual("DummyExceptionMessage", ex.Message);

            Assert.AreEqual("action2", calledActions.Content());

            calledActions.Clear();
            context.EndIsolationScope();
            Assert.AreEqual("action1", calledActions.Content());
        }
        public void CanAddCleanupActionAfterOneLevelWasPoppoed()
        {
            var context = new TestExecutionScopesManager("dummy", Functions.EmptyAction <IIsolationScope>());

            context.BeginIsolationScope("Level1", Functions.EmptyAction <IIsolationScope>());
            context.EndIsolationScope();
            var cleanupCalled = false;

            context.AddCleanupAction(() => cleanupCalled = true);
            context.EndIsolationScope();
            Assert.IsTrue(cleanupCalled, "Cleanup action hasn't been called");
        }
        public void CleanupActionInNestedIsolationLevelIsCalledOnlyOnPop()
        {
            bool cleaupWasCalled = false;
            var  context         = new TestExecutionScopesManager("dummy", ctx => { });

            context.BeginIsolationScope("dummyIsolationLevel", ctx => { });
            context.AddCleanupAction(() => cleaupWasCalled = true);
            context.EndIsolationScope();
            Assert.IsTrue(cleaupWasCalled);
            cleaupWasCalled = false;
            context.EndIsolationScope();
            Assert.IsFalse(cleaupWasCalled);
        }
        public void WhenMultipleCleanupActionsThrowExceptionsAnAggregatedExceptionIsThrown()
        {
            var context = new TestExecutionScopesManager("dummy", Functions.EmptyAction <IIsolationScope>());
            var ex1     = new Exception("1st Exception");
            var ex2     = new Exception("2nd Exception");

            context.AddCleanupAction(() =>
            {
                throw ex1;
            });

            context.AddCleanupAction(() =>
            {
                throw ex2;
            });

            var aggregatedEx = TestUtils.ExpectException <AggregateException>(() => context.EndIsolationScope());

            Assert.AreEqual(2, aggregatedEx.InnerExceptions.Count, "Invalid number of inner exceptions");
            Assert.IsTrue(aggregatedEx.InnerExceptions.Contains(ex1), "1st exception is not found in the aggergate exception");
            Assert.IsTrue(aggregatedEx.InnerExceptions.Contains(ex2), "2nd exception is not found in the aggergate exception");
        }
 /// <summary>
 /// Adds an action to be performed when the current execution scope ends.
 /// </summary>
 /// <param name="cleanupAction">A delegate to an action to perform on cleanup</param>
 /// <remarks>
 /// Actions that are registered with this method are called on cleanup, regardless whether the test passed or failed.
 /// You can call this methods any number of times, and the actions will be invoked in reverse order. This is useful because
 /// if there's a dependency between actions that you perform in the tests, then usually you must clean them up in the reverse
 /// order in order for the cleanup to succeed.
 /// Calling this method from the <see cref="AssemblyInitializeAttribute"/> decorated method, causes the
 /// action to be called when <see cref="AssemblyCleanup"/> is called.
 /// Calling this method from <see cref="ClassInitialize()"/> causes the action to be called after all tests in the class
 /// have completed (through the call to <see cref="ClassCleanup"/>).
 /// Calling this method from <see cref="TestInitialize"/> or from any test method (decorated with <see cref="TestMethodAttribute"/>)
 /// causes the actions to be called after the currently running test ends. Note that if there's an exception inside
 /// <see cref="TestInitialize"/>, the test method won't be called, but any cleanup actions that were already been registered
 /// will be.
 /// </remarks>
 public static void AddCleanupAction(Action cleanupAction)
 {
     TestExecutionScopesManager.AddCleanupAction(cleanupAction);
 }