How do I test an externally served app using Testacular + AngularJS - javascript

I have an app running on http://localhost:6543 - it's a Pyramid app.
This app serves the AngularJS app at /
This app uses socket.io itself
The question is: is it possible to test that application using those tools ?
I have this in my scenario.js file:
beforeEach(function() {
browser().navigateTo('http://localhost:6543/');
});
but the moment I launch testacular (with run or start), I get this error message:
Chrome 23.0 registration: should delete all cookies when user clicks on "remove all" button FAILED
browser navigate to 'http://localhost:6543/'
/home/abourget/myapp/jstests/scenarios/registration_scenario.js:9:5: Sandbox Error: Application document not accessible.
so I understand the browser doesn't give access to the iframe's document, because it'd be some Cross-Origin violation.
What I tried:
Proxying to my app using the Testacular web server (with the proxies option), but / would conflict with Testacular's own serving of its framework. Also, both apps would eventually try to use /socket.io and that would conflict also.
Doing the reverse (tweaking my app to proxy to Testacular's server), but then, we'd get the same issues with /socket.io.
Thanks for these great tools, btw!

Instead of having
beforeEach(function() {
browser().navigateTo('http://localhost:6543/');
});
change this to
beforeEach(function() {
browser().navigateTo('/');
});
and then in your testacular-e2e.conf.js file add:
proxies = {
'/': 'http://localhost:6543/'
};
You might still have other issues, but I can reproduce the "Sandbox Error: Application document not accessible." message with just the Pyramid Hello World App and this configuration problem.

We had a similar problem, and had already proxies and navigateTo('/'). We needed to add some urlRoot to avoid conflicts when loading socket.io. We simply added '/e2e' and that was enough to solve the conflict. Actually, there was a warning message when running testacular for this issue.

Related

window.onload with querystring Not working on deployed MVC6 project

I have been developing a website that can display some data. In the table, there is a button in each row to open a new window, where the user can see data related to that line.
I am using MVC 6 and I used Javascript to open the window and passing the 'id' parameter through querystring.
My code is:
The Parent View .cshtml:
The Button:
wButtonClass = "btn btn-warning openW";
<a href="javascript:void(0);" class="#wButtonClass" data-id=#id.ToString()>#buttonText</a>
The Script:
<script>
$(document).ready(function () {
$(".openW").click(function (e) {
var x = $(this).data("id");
var new_window = window.open('/MyView/HandleButton?id='+x, '_blank', 'left=200,top=150,width=1000,height=800,toolbar=1,resizable=0');
});
});
</script>
The Controller:
public IActionResult HandleButton(int id)
{
//Filling the List
return PartialView("DataView", myList);
}
So, it is working just fine from VS, but when I deploy the project to an IIS server (not on my machine), it opens the new window, and says "404 - Not Found", although the URL in the newly opened window is correct (the value is passed)
What could be the problem?
I've been looking through several forum questions, but couldn't find an answer.
Update 1:
Well, technicalliy, in the popup window, the URL is:
http://localhost/MyView/HandleButton?id=5
And it says in the 404 Error Details:
Requested URL http://localhost:80/MyView/HandleButton?id=5
Physical Path C:\inetpub\wwwroot\MyView\HandleButton
Update 2:
Well, I have finally found an answer. It looks very silly, but solved the problem.
I found it here:
IIS 8 Can't see partial view
I had to change the URL and add the application name:
So, instead of: /MyView/HandleButton?id='+x
I Typed: /MyWebApp/MyView/HandleButton?id='+x
Well, it works on the server, but doesn't work in VS. It will be fine (I just change the URL everytime I debug), but is there a way to do this more elegantly?
This could be expected if the routing is incorrect and the URL is incorrect. However, since your URL is correct and you still seeing a 404 error, it likely is an issue with the server configuration.
Verify that the IIS server has the correct permissions to access the
files and folders of your application.
Check that the IIS server has the correct .NET Framework version
installed and that your application is targeting the correct version.
Make sure that the IIS server has the correct MVC version installed
and that your application is targeting the correct version.
Check that the IIS server is configured to handle requests to the
.cshtml files.
Make sure that the MVC routing is configured correctly in the
web.config file of your application.
Check whether the IIS server is running in 32-bit or 64-bit mode.
Make sure that your application is built for the same mode.
Confirm that the server is able to find the DLLs and assemblies that
your application needs.
Check the event logs for any info.
This is italicized, and so
is this.
This is bold, just like this.
useEffect(() => {
var aScript = document.createElement("script");
aScript.type = "text/javascript";
aScript.src = "./js/main.js";
}, []);
You can combine them
if you really have to.

CherryPy terminates session after $window.location.href

For a Django 1.8 app with Angular.js & Django Rest Framework I'm using CherryPy server to serve the app over WSGI.
For this purpose I'm basically reusing this code, which works fine, until I use the following angular.js command in one of my *.js files:
url = patientDetailView + response.data.id + '/';
$window.location.href=url;
The view this link is pointing to requires (like other views as well) the user to be logged in(authenticated). However, although the user has been already logged in after $window.location.href=url django redirects to the login screen where the user needs to log-in again! My guess is that this may be due to the session being terminated (?). I don't see this problem while running the django dev server (./manage.py runserver)
Anybody can point me to why this is happening and how to fix that? I'm running out of ideas...

How to handle basic authentication with protractor?

I'm trying protractor to write a few tests in a non angular application. I have to login in a page trough basic authentication in google chrome, but i have no idea how.
I already tried baseUrl: 'https://username:password#url' and capabilities: {
'browserName': 'chrome',
'chromeOptions' : {
args: ['--login-user=foo', '--login-password=bar']
}
}
But none if these worked for me. Anyone knows how to do it? I'm having some hard time on it.
You can set the URL as http://username:password#yourdomain.example. Chrome will handle it!
The short answer is there is no easy way of doing it on chrome because they do not support modifying request headers -- see https://code.google.com/p/selenium/issues/detail?id=141 (title says response headers, but if you read it, it's for all headers).
That being said, there are ways to do it, albeit difficult.
1) Find a chrome extension/plugin that allows you to modify header. A simple search bring up many of them: https://chrome.google.com/webstore/search/modify%20header. You'll need to add the plugin to webdriver: see Is it possible to add a plugin to chromedriver under a protractor test?.
2) You can use browsermob-proxy (https://github.com/lightbody/browsermob-proxy); this way you route your traffic through the proxy, which would add the headers for you.
From the docs:
POST /proxy/[port]/auth/basic/[domain] - Sets automatic basic authentication for the specified domain
Payload data should be json encoded username and password name/value pairs (ex: {"username": "myUsername", "password": "myPassword"}
There's a node project that may help you, https://github.com/zzo/browsermob-node, but you would still need to set up your proxy server yourself.
Both ways for chrome are complex, but would get you what you want. (or you can stick with firefox and follow Robert's answer)
As of version 59 Chrome no longer supports URLs with embedded credentials.
To work around this I wrote the authenticator-browser-extension Node module, which might be useful if you're using Protractor, WebDriver.io or similar test runners.
To use the module install it from npm:
npm install --save-dev authenticator-browser-extension
And import in the protractor.conf.js:
const { Authenticator } = require('authenticator-browser-extension');
exports.config = {
capabilities: {
browserName: 'chrome',
chromeOptions: {
extensions: [
Authenticator.for('username', 'password').asBase64()
]
}
},
}
Pro tip: remember not to commit your credentials with your code, consider using env variables instead.
Hope this helps!
Jan
It's because Firefox doesn't trust any site by default with sending the Windows auth info over. Even if you change it in the configurations manually, it won't affect protractor because it opens Firefox with an isolated configuration each time you run your end to end tests.
You'll need to programatically set up a Firefox profile and set its preferences such that it would trust localhost (or some other website, depending where the pages are loaded from)
First, check out this example. It shows how you can set up the profile and how you can set preferences.
https://github.com/juliemr/protractor-demo/tree/master/howtos/setFirefoxProfile
What it does is that it modifies the homepage for each new tab. In the same manner (with the firefoxProfile.setPreference method) you can change the preferences responsible for trusting websites. They're called "network.automatic-ntlm-auth.trusted-uris" and "network.negotiate-auth.delegation-uris". You'll need to set them both to "localhost". (Again, if they're at some other place, it's obviously that URL)
hankduan's browsermob-proxy solution worked for me on Chrome - but the latest revisions of browsermob are using a thing called littleproxy which does not support auth headers. Thusly I had to do browsermob-proxy -port 9090 --use-littleproxy false, which got things working.
You may use Windows Credentials Manager to avoid this pop-up being constantly shown on every attempt to log in.
Add your credentials to the 'Generic' category there, restart browser (including background apps running).
Some explanation I currently have: this pop-up is not 'browser' specific, it is 'in the middle', between browser and domain credentials verification. Thus browser features (save password, autofill) do not work completely. By the same reason Protractor / Selenium etc. do not have complete control over that pop-up - it is by design of the domain authentication.
As not completely sure if it is the only reason there are some other hints:
- you may also need to add your site to the IE (IE, not Chrome) list of trusted sites (Chrome grabs information from there);
- check "Automatic logon with current user name and password" in IE (not Chrome) - may not work if credentials you are using for the site are different from those you use to login to the machine.
If you're reading this in 2019, with Angular 7/8, consider this:
https://www.npmjs.com/package/authenticator-browser-extension
I find it much easier than the solutions suggested above.

Can I/how can I translate a Selenium webdriver test script from node.js over to phantomjs - ghostdriver?

I recently began working with Selenium and to make life easier to start I was using node to run my scripts so that I could visually monitor the tests. My challenge now is to convert it so that it can be run as a headless test. Unfortunately, most of the resources that I have come across only address using phantomjs and ghostdriver with Java or Python. My boss wants me to run the test through phantomjs without Java or Python. Eventually these tests will be run remotely through a Linux VM on a server without a GUI. Currently I am testing using Mac OS X 10.8 and still have many bridges to cross in order to get to my goal.
My most important question firstly, is it possible to run a script from phantomjs through a port without the use of Java or Python? I have spent hours poring through as many resources as I could come across and I've come up with no solution.
If so, how can I properly initialize the test to run headless? Here is how I scripted the start of my functioning test. I want to properly switch the capabilities from firefox to phantomjs and be able to run it headless using the appropriate port. The rest of the test navigates to a specific site, logs in through a widget, then does further navigation to the area which I will build further tests on which to manipulate after I get this working.
var webdriver = require('selenium-webdriver'),
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
var server = new SeleniumServer("Path/selenium-server-standalone-2.39.0.jar", {
port: 8910
});
server.start();
var driver = new webdriver.Builder().
usingServer(server.address()).
withCapabilities(webdriver.Capabilities.firefox()).
build();
The test works perfectly, but I am new to this so there might be something foolish that I am overlooking. Please let me know what adjustments to make so that it will run headless through phantom. When I attempt to use node to run the script after switching capabilities to phantomjs it produces
"/Selenium/node_modules/selenium-webdriver/phantomjs.js:22
LogLevel = webdriver.logging.LevelName,
^
TypeError: Cannot read property 'LevelName' of undefined
at Object.<anonymous> (/Selenium/node_modules/selenium-webdriver/phantomjs.js:22:33)
That's a read only file that I can't adjust, any attempts that I made to define "LogLevel" or "LevelName" to the appropriate corresponding value (DEBUG, etc.) were fruitless.
And if I run it through phantomjs itself I get -
"Error: Cannot find module 'path'
phantomjs://bootstrap.js:289
phantomjs://bootstrap.js:254 in require"
(It also lists module 'http') -- (and various undefined function errors)
I feel that with that instance I didn't properly organize where the files for Selenium, phantomjs, and ghostdriver should go in order to play nice. I also removed the server setup portion and instead ran this first, then the script separately.
phantomjs --webdriver=8910
But it yielded the same result. All of my research to fix these issues turned up instructions for Java and Python but not Javascript by itself. Rather than chase through many rabbit holes I figured it wise to consult better minds.
If you know better than I do and that it is fruitless to attempt this without Java or Python, please let me know. If you know where the issue lies within my script and could propose a fix please let me know. I hope that I have properly described the nature of my issue and if you need more information I will do my best to provide it to you.
This is my second week working with Javascript so if you believe I am making a noob error you very well may be correct. Please, keep in mind that the script works through node with selenium webdriver.
Many thanks for your time!!!
~Isaac
This was a bit tricky but here is the solution I've pieced together:
var webdriver = require('selenium-webdriver'),
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer,
server = new SeleniumServer('/path/to/selenium/selenium-server-standalone-2.41.0.jar', {
port: 4444
}),
capabilities = webdriver.Capabilities.phantomjs();
capabilities.set('phantomjs.binary.path', 'path/to/phantom/bin/phantomjs');
var promise = server.start().then(function() {
var client = new webdriver.Builder().
usingServer(server.address()).withCapabilities(
capabilities
).build();
return {
'client': client,
'server': server
};
}, function(err) {
console.log('error starting server', err);
});
You can then use the promise with selenium's mocha-compatible test framework to hold the test till the server has started.
I found the documentation really helpful once i figured out the navigation is on the far right of the page. Here's the URL: http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver.html
Then you'll be stuck where I am. Getting selenium-webdriver to quiet down.

Loading Meteor .js in a local Html file in android

I am trying to work with Meteor. Now I have the entire setup running in my localmachine with apache2 and the meteor.js also works when browsing the same URL from Android Emulator's Browser . Now the main problem is that I need the functionality in my android app from a local URL and here the page is not able to load the remote js. I am loading the following html using WebViews loadURL method after setting the javascript as enabled .The js embedded in the html will be something like this
<script type="text/javascript" src="http://meteor.mywebserver.com/meteor.js"></script>
<script type="text/javascript">
window.onload = function()
{
Meteor.host = "meteor.mywebserver.com";
alert(textStatus);
// Call the test() function when data arrives
Meteor.registerEventCallback("process", commentsUpdate);
// Join the demo channel and get last five events, then stream
Meteor.joinChannel("demo", 0);
Meteor.mode = 'longpoll';
// Start streaming!
Meteor.connect();
// Handle incoming events
function commentsUpdate(data)
{
alert(data);
};});
After searching around a lot I tried this stackoverflow answer
To no avail . Can anybody help me find a work around here , I cant use a local meteor.js as it wont work.
Thanks
This has since been addressed in Meteor by way of integrated Cordova, which you can read about here. Basically, you tell Meteor that you want to add the Android platform to your app, and it builds the Android project files for you. Your app will look as if it's running native, but it's really just running in a light app surrounding a "web view". In iOS this is done using WebKit, but I think in Android it depends on the version of the OS.
You will still need to deploy your app to the Play store, which requires signing the app and all.

Categories

Resources