Cross Browser Testing using Coded UI - cross-browser

I'm trying to run Coded UI tests in chrome. The code is:
BrowserWindow.CurrentBrowser = "Chrome";
BrowserWindow brw = new BrowserWindow();
brw = BrowserWindow.Launch(new System.Uri("http://www.google.com"));
But I am getting run time error: "value cannot be null.
Parameter name windowhandle".
I have VS2012 Ultimate and have also installed 'Selenium components for Coded UI Cross Browser Testing'.
Am I doing something wrong or something else needs to be checked?

Created a new Unit Test Project with all Selenium and Browser Drivers. Now I am able to navigate to the URL and run the application.

Related

How to run code in an iOS app from a UI test in Xcode 7?

Is there a way to run code in the app from a UI test in Xcode 7? This is possible with application tests (since the tests run in the app), but there doesn't appear to be a simple way with UI tests.
Has anyone figured out a workaround?
The most straight forward way to run code in the app you are executing your app from UI tests is to supply launchArguments via XCUIApplication.
ui test code
import XCTest
class UITestUITests: XCTestCase {
override func setUp() {
super.setUp()
let app = XCUIApplication()
app.launchArguments += ["-anargument", "false","-anotherargument","true"]
app.launch()
}
}
app code
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
print("All arguments: \(NSProcessInfo.processInfo().arguments)\n\n")
print("anargument: \(NSUserDefaults.standardUserDefaults().boolForKey("anargument"))")
print("anotherargument: \(NSUserDefaults.standardUserDefaults().boolForKey("anotherargument"))")
return true
}
app output when launched from ui test:
All arguments: ["/...../AnApp.app/UITest", "-anargument", "false", "-anotherargument", "true"]
anargument: false
anotherargument: true
UI Testing runs in a separate process from your app. There is currently, as of Xcode 7.1.1, no way to interact directly with the production app's code from the framework.
Every interaction must route through accessibility. This means that you could wire up a button that executed code in your app, then have the tests call that button. This is obviously not scalable and I would recommend against it.
Maybe there is another way to achieve your goals? What exactly are you trying to accomplish?
I'm thinking of passing an environment variable to the app when testing which launches an embedded HTTP server. Then I can communicate with the app through the server. Crazy, right? And yet, I can't believe nobody has done this yet.
My biggest concern with this approach is that the embedded server will be in the production app. I'm not sure if that is a problem, or if there's a simple way to only include it when running UI tests.

Viewing console output from TVJS

I'm working with the tvOS beta 3 and trying to do some basic debugging on the tvml/tvjs side of things.
Messages logged via console.log(...) in my js files don't appear in the main Xcode output window.
Is there somewhere else I can find these messages or a setting which needs to be configured?
You should actually use the debug console in Safari. (The developer forum suggests you use Safari 9 and upgrade to El Capitan, both of which I have so haven't been able to test with inferior version)
Open Safari > Develop menu > Simulator
Your app name should appear here once and from there you can use the console.
Give it a few seconds to appear, it's not always instantaneous.
You must give a name to the Bundle Identifier in General/Identity (com.yourcompany.appname) to appear the app in the developers tool.
If you are developing a hybrid application (TVML/TVJS + Swift) with TVMLKitchen you can implement a logging function in Swift and use it in the TVJS code. For my projects I use the following code:
Kitchen.appController.evaluateInJavaScriptContext({context in
let printInJS : #convention(block) (NSString!) -> Void = {
(string : NSString!) -> Void in
print("Log: \(string)\n")
}
context.setObject(unsafeBitCast(printInJS, AnyObject.self), forKeyedSubscript: "printInJS")
})

View all XCUIElements in current screen

In UI/Automation Testing using Xcode 7, is there a way to list all of the XCUIElements on an app screen? Like in a tree or list, or even something in the Xcode UI? I can record tests for the app under test using clicks, but when I go to run the test, it fails. It fails because it can't find the XCUIElements from the generated code.
You can view it in Xcode hierarchy debugger.
From Apple Docs:
To enter the view debugger, run your app in Xcode and click the Debug View Hierarchy button in the debug bar.
You can debug the state of UI element using,
XCUIElement.debugDescription
It returns a snapshot of UIView in html format with a nice look up into the UI elements state with properties like element type(e.g textField, button), traits like focussed, enabled and values e.g placeholderValue.
You can also use accessibilityInspector app to look into accessibility attributes for the UI Elements on the view and verify that elements have accessibility properties set correctly.
Another handy tool to investigate the view is new hierarchy viewer which can be invoked during recording from debug console toolbar or Debug Navigator filter when you enable breakpoint in your test code.
Xcode 7 also has a nice test reporting under Report Navigator which can help you drill down exact reason with the test failure. e.g
UI Test Activity:
Assertion Failure: Asynchronous wait failed: Exceeded timeout of 10 seconds, with unfulfilled expectations: "Expect predicate `exists == 1` for object "Logout" Button".
Hope this helps.

Setting profile/capabilities for chrome and ie8 through selenium

I am automating a test on aws.amazon.com to check whether the resources that i created using aws cli were successfully created or not using selenium webdriver. As the site falls out of my company network, to access the site i need to provide domain user/password in modal pop up that comes before hitting the url for the site.
i am not sure , but solution to this problem is to set profile/capability in the browser settings through the code. before hitting the url.
i have achieved that in firefox as follows
FirefoxProfile profile = new FirefoxProfile();
profile.addExtension(new File(Constants.FIREFOX_ADDON_PATH));
profile.setPreference("extensions.enabledAddons", "FireXPath%40pierre.tholence.com:0.9.7.1,proxyauth%40lammersoft.com:0.1.2,%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:37.0.1");
profile.setPreference("extensions.proxyauth.authtoken","c3ViaGFtdDpub3YwNDIwMTQ=");
How to do the same in chrome and ie8 ?
i went through this but not able to comprehend anything.Also what does .xpi and .crx file has to do with all of this ?
This is pop up image for chrome
This is pop up image for IE8
The popup is a Windows Http Authentication popup and cannot be handled by using Selenium Webdriver. You will have to use either Robot Class or AutoIT to handle it.
1. Using Robot Class:
Alert authenticationWindow = driver.switchTo().alert();
// Type the username/email.
authenticationWindow.sendKeys("<username/email address>");
// Shift cursor focus to password input text field.
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
// Type the password in password field. [ Selenium does not know at this point that the cursor focus is shifted, so calling Alert class instance sendKeys() will cause password to be typed in username field. So, we are copying the password first to windows clipboard and then pasting it directly into the password field using Robot class instance ]
StringSelection stringSelection = new StringSelection("<user password>");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection,null); robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
// Accept the authentication window.
robot.keyPress(KeyEvent.VK_ENTER);
2. Using AutoIT:
This link provides good information on how to use AutoIT alongwith Selenium: http://www.toolsqa.com/selenium-webdriver/autoit-selenium-webdriver/
Here is what you have to do:
Download/install AutoIT
You will be able to create .au3 scripts using AutoIT SciTe Editor
Compiling the .au3 script will give you a .exe file
Then you can invoke the .exe file from your Selenium script using
Runtime.getRuntime().exec("D:\AutoIt\AutoItTest.exe");
You can get the properties of a window using the AutoIT Window Info (x86) or (x64). Example, title / status bar of a window.
AutoIT also has Au3 Recorder so that you can record your actions that are related to the remote desktop.
Below is a sample script that automates Http authentication:
WinWaitActive("Web page title","","10")
If WinExists("Web page title") Then
Send("userid{TAB}")
Send("password{Enter}")
EndIf
3. Using AutoITx4Java:
Check this library AutoITx4Java - https://code.google.com/p/autoitx4java/
Download Jacob, AutoIT (refer the above link)
Add jacob.jar and autoitx4java.jar to your library path.
Place the jacob-1.15-M4-x64.dll file in your library path.
Sample Code
File file = new File("lib", "jacob-1.15-M4-x64.dll"); //path to the jacob dll
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
AutoItX x = new AutoItX();
String notepad = "Untitled - Notepad";
String testString = "this is a test.";
x.run("notepad.exe");
x.winActivate(notepad);
x.winWaitActive(notepad);
x.send(testString);
Assert.assertTrue(x.winExists(notepad, testString));
x.winClose(notepad, testString);
x.winWaitActive("Notepad");
x.send("{ALT}n");
Assert.assertFalse(x.winExists(notepad, testString));

play DRM content in chrome driver

I'm writing some selenium tests for a HTML5 player playing DRM content, the player works fine in Chrome when I test it manually, but nothing is loaded or played in the latest chrome driver if I run my test cases.
Is it because of the drm content isn't authorized to play in chrome driver or something else?
I have no issues running tests for other functions written in selenium.
Any ideas?
Chromedriver launches Chrome with --disable-component-update switch by default, which disables the NaCl (Native Client) support, which is in turn required to load DRM modules (e.g. Widevine Modular DRM).
To get around this, you need to tell the driver not to launch Chrome with this switch, by building the driver with excludeSwitches option, specifying disable-component-update parameter. For example (JS):
var webdriver = require('selenium-webdriver');
var chrome = require("selenium-webdriver/chrome");
var capabilities = new webdriver.Capabilities.chrome();
var chromeOptions = {
'args': ['--user-data-dir=C:/ChromeProfile'], // start with pre-configured Chrome profile
'excludeSwitches': ['disable-component-update'] // stop breaking Native Client support
};
capabilities.set('chromeOptions', chromeOptions);
var driver = new webdriver.Builder().
withCapabilities(capabilities).
build();
driver.get('http://...');
Or using Python bindings:
from selenium import webdriver
def buildDriver():
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['disable-component-update'])
options.add_argument('--user-data-dir=C:/Temp/ChromeProfile')
return webdriver.Chrome(chrome_options=options)
Hope that helps..
-- ab1
Issue 886: Enabled PNaCl Components in ChromeDriver - Enhancement
If you cannot get #Chainik's answer to work, try this out. It worked for me.
As per https://bugs.chromium.org/p/chromedriver/issues/detail?id=1140 you can work around this issue by doing a few things.
manually start chrome from terminal/command prompt with these command line arguments --
google-chrome --user-data-dir=/path/to/any/custom/directory/home/user/Desktop/Chromedir --profile-directory="Profile 1" --remote-debugging-port=7878
make sure "Profile 1" is already existing in the same --user-data-dir (make usre Profile 1 has necessary chrome://components/ to run Netflix when launched manually)
you can use any free port in place of 7878
verify that http://localhost:7878 is running and returns value.
now connect to the remote-debugging-port=7878 via chromedriver with code below
Verify chrome://components/
I put mine into a .bat file, but you could do the same for a bash script or whatever:
C:/Program Files (x86)/Google/Chrome/Application/chrome.exe --user-data=c:/temp/chromeprofile --profile-directory="Profile 1" --remote-debugging-port=7878
Then set the debugger address in your code to use the browser:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
cr_options = Options()
# This line is where the "magic" happens.
cr_options.add_experimental_option('debuggerAddress','127.0.0.1:7878')
browser = webdriver.Chrome(chrome_options=cr_options)
browser.get('https://www.google.com')
browser.get('chrome://components/')
I'm post a java version of Chainik's answer as a reference for those using Java, please let me know if there's anything wrong.
ChromeOptions options = new ChromeOptions();
List<String> list = new ArrayList<String>();
list.add("disable-component-update");
options.setExperimentalOption("excludeSwitches", list);
options.addArguments("user-data-dir=/Users/myname/Library/Application Support/Google/Chrome/Default");
java.lang.System.setProperty("webdriver.chrome.driver","/usr/bin/chromedriver");
Webdriver driver = new ChromeDriver(options);
Here is an article about chromedriver capabilities and options.
This is late but might help someone else. I was able to get around this and play videos by not using a headless browser.
In Python,
options = Options()
options.headless = False
webdriver.Chrome(executable_path='path/to/chromedriver', options=options)