How do I keep the browser open after a coded ui test finishes? - coded-ui-tests

I'm using Visual Studio 2012 Coded UI tests for a web application. I have a test for logging into the app which starts the browser, locates the login dialogue, enters credentials, and then clicks ok. I have an assertion which checks for the correct url after the login. This test appears to function correctly. My problem is that it closes the browser after the test runs. I need to keep the browser open, so I can run the next test in my sequence. How do I do this?
At the moment, I don't have anything in my [TestCleanup()] section. I'm assuming that what I'm looking for goes here, but so far I haven't had a lot of luck figuring out what that is supposed to be.

I don't have the original source where I found this solution :(
You can have a method like the one showed below. This method needs to be called in TestSetup. Also declare a class level variable _browserWindow of the tyep BrowserWindow
private void SetBrowser()
{
if(_browserWindow == null)
{
BrowserWindow.CurrentBrowser = "ie";
_browserWindow = BrowserWindow.Launch("http://www.google.com");
_browserWindow.CloseOnPlaybackCleanup = false;
_browserWindow.Maximized = !_browserWindow.Maximized;
}
else
{
BrowserWindow.CurrentBrowser = "ie";
_browserWindow = BrowserWindow.Locate("Google");
_browserWindow.Maximized = !_browserWindow.Maximized;
}
}

Ok, so what I needed to have happen was the launch and login before each test. I thought what I wanted was to run the browser and login test first, and then each additional test. After reading more, I've decided what I actually wanted was to run this logic as initialization code for each test. I've done that by adding this code to the default [TestInitialize()] generated when I started the coded ui project in Visual Studio 2012.

I have found the following method to work for my data driven coded UI test in Visual Studio 2015.
You will want to use [ClassInitialize] and get your browser open and direct it according to where your [TestMethod] begins.
Use [ClassCleanup] to release the resources after all the methods in the test class have been executed.
You can redirect test methods different after the class has been initialized by using the [TestInitialize] and clean-up test using the [TestCleanup]. Be careful with those though because they will occur for each test method and if it closes your browser instance your following test will fail.
private static BrowserWindow browserWindow = null;
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Playback.Initialize();
browserWindow = BrowserWindow.Launch(new Uri("http://198.238.204.79/"));
}
[ClassCleanup]
public static void TestCleanup()
{
browserWindow.Close();
Playback.Cleanup();
}

Related

Loaded SWF's wont preform their functions in air

Back for some help! So I am making an AIR application that loads SWF's into a container to be viewed by the user. However when I load the files into their containers, the SWF's that are loaded are unable to execute their own code. IE press an invisible button on the loaded SWF and it changes colour. I tried to google solutions for this since Security.allowDomain("*"); is throwing this error in flash. However from what I have read, AIR doesn't allow loaded swfs to execute code for some security reason but im not 100% sure on that either.
SecurityError: Error #3207: Application-sandbox content cannot access this feature.
at flash.system::Security$/allowDomain()
at BugFree()[D:\Desktop\BugFree\BugFree.as:72]
Without the Allow domain it throws this security error when attempting to click the invisible button.
*** Security Sandbox Violation ***
SecurityDomain 'file:///D:/Desktop/Rewritten Tester/TechDemoSwordNew.swf'
tried to access incompatible context 'app:/BugFree.swf'
*** Security Sandbox Violation ***
SecurityDomain 'file:///D:/Desktop/Rewritten Tester/TechDemoSwordNew.swf'
tried to access incompatible context 'app:/BugFree.swf'
SecurityError: Error #2047: Security sandbox violation: parent:
file:///D:/Desktop/Rewritten Tester/TechDemoSwordNew.swf cannot access
app:/BugFree.swf.
at flash.display::DisplayObject/get parent()
at TechDemoSwordNew_fla::Button_Play_21/onButtonPress()
This only shows in the Animate output bar. When I publish it, with application with runtime embeded, and open the exe it throws no errors but the invisible button still doesnt work.
Here is the code for the swf being loaded.
btnButton.addEventListener(MouseEvent.CLICK, onButtonPress, false, 0, true);
function onButtonPress(event:MouseEvent):void
{
MovieClip(parent).play();
}
stop();
This is timeline code within the button since that is how the game company who put my item in game did it. I originally submitted it with it all done in classes but that is besides the point. When the button is pressed the loaded SWF should play and then stop. But I get the above mentioned Sandbox violation.
The code used to load the SWF is below
public function WeaponLoad()
{
if(FileMenu.WeaponFileTxt.text != "")
{
LoadWeapon(FileMenu.WeaponFile.nativePath);
}
else if(FileMenu.WeaponFileTxt.text == "")
{
Character.mcChar.weapon.removeChildAt(0);
Character.mcChar.weaponOff.removeChildAt(0);
}
}
public function LoadWeapon(strFilePath: String)
{
WeaponLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, CompleteWeaponLoad);
WeaponLoader.load(new URLRequest(strFilePath), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)));
}
public function CompleteWeaponLoad(e: Event)
{
var WeaponClass: Class;
if (MiscMenu.WeaponSelect.MainClick.currentFrame != 3)
{
try
{
trace("WeaponOff");
WeaponClass = WeaponLoader.contentLoaderInfo.applicationDomain.getDefinition(FileMenu.WeaponLinkTxt.text) as Class;
this.Character.mcChar.weapon.removeChildAt(0);
this.Character.mcChar.weaponOff.removeChildAt(0);
this.Character.mcChar.weapon.addChild(new(WeaponClass)());
}
catch (err: Error)
{
trace("Either the weapon class doesnt exist or it is wrong");
this.Character.mcChar.weapon.removeChildAt(0);
this.Character.mcChar.weaponOff.removeChildAt(0);
}
}
else if (MiscMenu.WeaponSelect.MainClick.currentFrame == 3)
{
try
{
WeaponClass = WeaponLoader.contentLoaderInfo.applicationDomain.getDefinition(FileMenu.WeaponLinkTxt.text) as Class;
this.Character.mcChar.weapon.removeChildAt(0);
this.Character.mcChar.weaponOff.removeChildAt(0);
this.Character.mcChar.weapon.addChild(new(WeaponClass)());
this.Character.mcChar.weaponOff.addChild(new(WeaponClass)());
}
catch (err: Error)
{
trace("Either the weapon class doesnt exist or it is wrong");
this.Character.mcChar.weapon.removeChildAt(0);
this.Character.mcChar.weaponOff.removeChildAt(0);
}
}
}
Any help would be apreciated since I have no idea how to change any security sandbox settings within the publish settings since it is greyed out for me. Like I said I tried googling it but I couldn't seem to come up with any answers. Also worth noting is im a self taught novice and I do not know a lot of things in regards to AS3. I know my codes could be cleaner and I plan to clean it up and properly reduce memory consumption once I have the base program up and running. Thank you for the help!
It seems that you're not setting the application domain properly. Here is the code included in as3 documentation:
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("[file path].swf");
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null);
loader.load(url, loaderContext);
Use it in your LoadWeapon function.
In the meantime try not to use Uppercase letters for starting variables and method names. In ActionScript names starting with Uppercase represent Class names. It will widely improve readability of your code.
Can't you bundle your swfs with the AIR app and use File class to load them? If you want to use classes from the swfs, maybe consider making swc library?

how to drive DJ NativeSwing thread separately from my own thread

Nowadays, I am working on a java swing application using DJ NativeSwing as my embed browser to do something automatic work. The scenario of my application is that a user click start button and the embed browser auto click some position of the current page and then redirect to another one and then execute some other operations like click or something other. Now here is my solution. First, I will define a webbrowser class (extends JWebBrowser) and webbrowser listener class (implements WebBrowserListener), which represents a webbrowser and contains loadingProgressChanged, windowOpening and so on separately. Second, I define a thread class to do some logic computing and execute my browser operations as mentioned above by webbrowser.executeJavascript. At last, I add mouseListener for start and stop button to start or stop the task. When I open my application, the JFrame add the browser and its listener class. I click the start button, the browser works and will click the target position as I expected and then the page will redirect to another one. As we all know, js code can’t be executed until the page was loaded completely. So I set a global flag to check whether the page has loaded completely or not in loadingProgressChanged (code:if(e.getWebBrowser().getLoadingProgress() == 100)globalflag = true;) within webbrowser listener class. And in the thread class, I use code( while(globalflag == false){Thread.sleep(500);}) after first click to detect if the current page was loaded completely. However, when browser first click the target position and the page redirects successfully, I find that the current page has changed but blocked. After some debugging, I find it. In my thread class, browser will execute js code by webbrowser.executeJavascript("document.getElementById(‘target’).click();") to click the target position and then java code (while(globalflag == false){Thread.sleep(500);}) to detect if the current page was loaded completely and then execute some other java code. I find that the globalflag will never change and the current page’s loadingProgressChanged listener will never work because the java code (while(globalflag == false)). Because after I remove all java code after the first webbrowser.executeJavascript("document.getElementById(‘target’).click();"), the current page’s loadingProgressChanged listener works and the page was not blocked. With the DJ NativeSwing demo, I could execute my js in the loadingProgressChanged. However, I want to do a series of operations with my browser and also want to stop the task whenever need. So, I prefer to my solution for my demand rather than the provided one by demo. So, I wonder that after webbrowser.executeJavascript the DJ NativeSwing thread will wait my thread? And, in my software architecture, does anyone could have any suggestions? Thanks a lot. Any suggestion is appreciated!
PS.my application works fine with jdic-0.9.5, but it supports IE7 only.
I paste my code here to demonstrate my problem:
After I click the start button in JFrame, I will new a thread as follow
public class MyVisit implements Runnable{
private void doClick1(){
webbrowser.executeJavascript("document.getElementById('n').value='test'");
webbrowser.executeJavascript("document.getElementById('f').submit()");
}
public void run() {
globalFlag=false;
webbrowser.executeJavascript("document.getElementById(‘t’).click();") ;
while(!globalFlag){
Thread.sleep(500);
}
this.doClick1();
}
}
listener:
public class MyListener implements WebBrowserListener {
…
public void loadingProgressChanged(WebBrowserEvent e) {
if (e.getWebBrowser().getLoadingProgress() == 100) {
globalFlag=true;
}
}
}
DJ Native Swing enforces the Swing approach to threading: manipulate the components in the AWT Event Dispatch thread (a.k.a. UI thread). But also, do not block that thread, because listeners are triggered in that thread too.
So, you should not have a "while" loop in the UI thread, but should instead spawn a new thread. I hope your global variable is volatile, or AtomicBoolean or all accesses to it protected by synchronized block, otherwise you might have interesting threading side effects.

MVVMCross: CreatePresenter() is never called in MvvmCrossTouch setup

I would like to define a custom presenter to customise my UI a little, to implement a split view on iPad and so on. I defined this class:
class ProjectPresenter : MvxTouchViewPresenter
{
public ProjectPresenter(UIApplicationDelegate applicationDelegate, UIWindow window) : base(applicationDelegate, window)
{
}
public override void Show(MvxViewModelRequest request)
{
IMvxTouchView viewController = this.CreateViewControllerFor(request);
this.Show(viewController);
}
}
And I registered it in my MvxTouchSetup class like so:
protected override IMvxTouchViewPresenter CreatePresenter()
{
MvxTrace.Trace("Creating the presenter!");
return new ProjectPresenter(this.ApplicationDelegate, this.Window);
}
However, breakpoints in the Show() method are never hit. I tried adding breakpoints to all overloads of Show(), ChangePresentation(), etc, but they are never hit. Now, I know that Xamarin.iOS is fairly unreliable where breakpoints are concerned but even putting in trace methods yields no joy. I even replaced the CreatePresenter() method with a method that throws an exception and the app didn't crash.
Other modifications to my application show up when I deploy them, so this isn't some sort of caching problem, although I have cleaned both the sources on my PC and on my Mac as well. Furthermore, the breakpoint in the constructor of my setup class is being hit, so this is perhaps not even a Xamarin-related problem at all.
I'm guessing that I'm either relying on older documentation or I'm doing something very very silly (I'm guessing the latter).
The only reason I can think that CreatePresenter wouldn't be called is if you are using the older 'presenter-based' constructor for your Setup
MvxTouchSetup provides two different constructors:
protected MvxTouchSetup(MvxApplicationDelegate applicationDelegate, UIWindow window)
{
_window = window;
_applicationDelegate = applicationDelegate;
}
protected MvxTouchSetup(MvxApplicationDelegate applicationDelegate, IMvxTouchViewPresenter presenter)
{
_presenter = presenter;
_applicationDelegate = applicationDelegate;
}
from https://github.com/MvvmCross/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Touch/Platform/MvxTouchSetup.cs#L39
By default in Nuget-based projects and in most of the MvvmCross samples, the first of these is used.
However, the second form actually existed first and so it's still around for historical reasons - to prevent older apps from breaking. If you use it, then the CreatePresenter() is not used - it's not needed because you've supplied a presenter during construction.

how to generate code in second UImap from existing recording

I am new to codedUI and for a start I am reading a lot about what should be a best practice.
I have read that if you are using complex application that is advisable to use multiple UImaps. Although I can not see a benefit at the moment I have created small project with two UImaps.
In the first initial setup (with initial UImap and CodedUITest1) I can choose whether to use Test builder or existing action recording for generating code. What ever I do it 'goes' to initial UImap. When I create new UI, test builder is started and I can record some actions and when I save it, it is added to newly created UImap in my case called AdvanceSettings. But I can not generate code from existing recording. Why is that? I would like to create automated test cases based on manual test cases with recordings.
Below is my code. I am using CodedUITest1 class for both UImaps. Should I use new class for
every UImap?
If you have some comments on code please do write some.
As I see it. Multiple UImaps are used if you have complex application so you can more easily change something. every GUI element has one UImap so if something changes on that GUI you only edit that UImap. But if you have one UImap and you use proper naming you can also easily replace or re-record certain method. So I am missing big picture with multiple UImaps.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Input;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using EAEP.AdvanceSettingsClasses;
namespace EAEP
{
/// <summary>
/// Summary description for CodedUITest1
/// </summary>
[CodedUITest]
public class CodedUITest1
{
public CodedUITest1()
{
}
[TestInitialize]
public void InitializationForTest()
{
this.UIMap.AppLaunch();
}
[TestMethod]
public void MainGUIMethod()
{
// To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
// For more information on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
this.UIMap.AssertMethod1();
this.UIMap.RestoreDefaults();
this.UIMap.AssertMethod1();
}
[TestMethod]
public void AdvanceSettignsWindowMethod()
{
AdvanceSettings advanceSettings = new AdvanceSettings();
advanceSettings.MoreSettingsReopenedAfterCancel();
this.UIMap.AssertVerificationAfterCancel();
advanceSettings.MoreSettingsReopenedAfterOK();
this.UIMap.AssertVerificationAfterOK();
}
#region Additional test attributes
// You can use the following additional attributes as you write your tests:
////Use TestInitialize to run code before running each test
//[TestInitialize()]
//public void MyTestInitialize()
//{
// // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
// // For more information on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
//}
////Use TestCleanup to run code after each test has run
//[TestCleanup()]
//public void MyTestCleanup()
//{
// // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
// // For more information on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
//}
#endregion
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
private TestContext testContextInstance;
public UIMap UIMap
{
get
{
if ((this.map == null))
{
this.map = new UIMap();
}
return this.map;
}
}
private UIMap map;
}
}
You cann't use multiple UI Maps with the from existing recording feature. this feature always generates code in a map called UIMap. I've explained a bit about these limitation in a blog post i did about integrating specflow with Coded Ui tests
http://rburnham.wordpress.com/2011/05/30/record-your-coded-ui-test-methods/
If you want to use Multiple UIMaps for better maintainability you have to use this method
Record each action individually by right clicking the UIMap and selecting Coded UI Test Builder.
Manually wire up the test to the actions by creating a blank Coded UI Test, update the UIMap it references and then in the test methods call the required actions to perform the test.
Its a limitation that makes what is good about the MTM integration pointless.
Having multiple UIMaps speeds the test execution. Additionally this makes editions, assertions, properties and settings a lot easier.
To create tests for the second UIMap you just right click on it and press "Edit With Coded UI Test Builder"
Regarding the But I can not generate code from existing recording. Why is that? I have no clue - what do you mean by can not?

Process CloseMainWindow() function doesn't work

I have a test method which requires Internet Explorer to be opened and closed numerous times during the test. I have been creating a process like this:
Process process = Process.Start(...);
And closing it like this:
process.CloseMainWindow();
However, I have found that I can only call this method once, otherwise I get the error message, "Process has exited, so the requested information is not available".
Once I have closed the process, I would then re-launch Internet Explorer. e.g.
process = Process.Start(...);
But this didn't work. I also tried nulling the Process variable before calling the Process.Start() method, but this didn't work.
I also tried using process.Kill(), but this caused problems too.
What is the correct way to do this?
UPDATE: Code
Process Browser;
[TestInitialize]
public void TestSetup()
{
Browser = TestBase.LaunchBrowser();
...
Browser.WaitForInputIdle();
Browser.CloseMainWindow();
Browser = null
Browser = Process.Start("IExplore.exe", ...);
}
[TestMethod]
public void MyTest()
{
// do things
Browser.Kill();
Browser = Process.Start("IExplore", "www.adifferentwebpage");
}
[TestCleanup]
public void TestCleanup
{
Browser.Kill();
}
I suggest to create another process without reusing the same variable.
Encapsulate your code inside a using statement to properly close and dispose the process variable
using(Process process = new Process())
{
// do you stuff
process.Start(.....);
process.CloseMainWindow();
}
Also remember that calling CloseMainWindow doesn't gurantees that the process will close. It only sends a request to close to the main window of the process. If the application ask for user confirmation before quitting it can refuse to quit.
I found a solution, but it only applies to those who have access to the Coded UI test DLL's (which I believe comes with Visual Studio Ultimate and Premium).
Therefore I will change the tags on the question.
If you create a Coded UI test project, these DLL references will already be there, but this using reference is what you need:
using Microsoft.VisualStudio.TestTools.UITesting;
To create a browser window:
BrowserWindow browser = BrowserWindow.Launch(new System.Uri("www.whatever.com"));
To close:
Browser.Close();
This worked no matter how many times I needed to relaunch the browser. This API also includes a multitude of other handy features like the ability to delete cookies, change the URL of the current browser, resize the window etc.

Resources