I have written a script for CasperJS which is supposed to read a json file which has a list of sites with details on how to log into, and run the search pages for each keyword.
I have tested my code with one site which worked, however for the second site, it logs in but when it attempts to goto a search page it returns an empty page.
This is my casper setup:
casper = require('casper').create(
clientScripts: [
'jquery.min.js'
]
verbose: true
logLevel: "debug"
)
This is the loop code:
casper.start().each sites, (self, site)->
search_results[site.title] = {}
self.thenOpen site.login.path,
method: "get"
data: site.login.getdata
, ->
#echo "Visiting Login Page: #{site.login.path}"
self.then ->
self.then ->
#evaluate (ufield,user,pfield,pass)->
jQuery(ufield).val(user)
jQuery(pfield).val(pass)
,
ufield: site.login.form.username.element
user: site.login.form.username.value
pfield: site.login.form.password.element
pass: site.login.form.password.value
self.then ->
#echo "Added formdata"
self.then ->
#click "#{site.login.form.element} #{site.login.form.submit}"
self.then ->
#echo "Submitted form"
self.then ->
#waitUntilVisible site.login.form.wait.element, ->
#echo 'Page Loaded'
, ->
#echo "Login Failed"
#exit 1
, max_timeout
self.each keys, (self, skey)->
self.thenOpen site.search.path,
method: "get"
data: site.login.getdata
, ->
#echo "Visiting Search Page: #{site.search.path}, for #{skey}"
self.then ->
#echo #page.content
#waitUntilVisible "#{site.search.form.element} #{site.search.form.query.element}"
, ->
#echo "Search Form Visible"
, ->
#echo "Search Visit Failed"
#exit 1
, max_timeout
self.then ->
#evaluate (key, feild)->
jQuery(feild).val(key)
,
key: skey
feild: site.search.form.query.element
self.then ->
#echo "Added searchdata"
self.then ->
#click "#{site.search.form.element} #{site.search.form.submit}"
self.then ->
#echo "Submited Search"
self.then ->
#waitUntilVisible site.search.form.wait.element
, ->
#echo "Search Results Visible"
, ->
#echo "Search Failed"
#exit 1
, max_timeout
self.then ->
result_links = #evaluate (linktag)->
res = []
res_els = __utils__.findAll(linktag)
Array.prototype.forEach.call res_els, (e)->
href = e.getAttribute("href")
label = jQuery(e).text()
res.push {href: href, label: label} if href?
res
,
linktag: "#{site.search.threads.element} #{site.search.threads.link.element}"
self.then ->
utils.dump result_links
search_results[site.title][skey] = result_links
Console output to do with the fail is as follows:
[debug] [phantom] opening url: http://www.cyclingforums.com, HTTP GET
[debug] [phantom] Navigation requested: url=http://www.cyclingforums.com/, type=Other, lock=true, isMainFrame=true
[debug] [phantom] url changed to "http://www.cyclingforums.com/"
[debug] [phantom] Automatically injected jquery.min.js client side
[debug] [phantom] Successfully injected Casper client-side utilities
[info] [phantom] Step 50/68 http://www.cyclingforums.com/ (HTTP 200)
Visiting Search Page: http://www.cyclingforums.com, for track
[info] [phantom] Step 50/68: done in 63268ms.
[info] [phantom] Step 51/68 http://www.cyclingforums.com/ (HTTP 200)
<html><head></head><body></body></html>
[info] [phantom] Step 51/68: done in 63352ms.
[info] [phantom] Step 52/69 http://www.cyclingforums.com/ (HTTP 200)
[info] [phantom] Step 52/69: done in 63452ms.
[warning] [phantom] Casper.waitFor() timeout
Search Visit Failed
Why is the page responding with an empty page?
EDIT: Through testing with other sites, it seems that the base code works, but this one site seems to be causing issues.
Related
I am trying to setup a POST request method using the "Add Item" operation within a REST API for my portal so that the PNG images can be add and later updated. Currently my script uploads the item to the portal but when i try to download the file or share it then it opens a page saying "Item does not have a file . Error 500" I assume its something to do with how i am building the POST request. How should i send the file over the POST request so that i can later download and update the file . Here is my current code:
def add_item(username,files,type,title):
"""
Add an item to the portal
Input:
- file: path of the the file to be uploaded
- username: username of user uploads the item
Return:
- Flag with a list of messages
"""
# set request header authorization type
header = {
'Authorization': f'Bearer {token}'
}
# build url
u_rl = f"{portal}/sharing/rest/content/users/{username}/addItem"
# search for id
req = requests.post(url=u_rl, headers=header,files=files,data={ "type":type,"title":title,"f": "json"})
response = json.loads(req.text)
if 'error' in response.keys():
error = response["error"]
raise Exception(
f"Error message: {error['message']}", f"More details: {','.join(error['details'])}")
return response["success"] if 'success' in response.keys() else False
if __name__ == "__main__":
user = input("input your USERNAME: ")
password = getpass.getpass("input your PASSWORD: ")
portal = "https://cvc.portal"
token = generate_token(user, password, portal=portal)
files = {'upload_file': open(r'C:\Users\test.png','rb')}
type='Image',
title='An image'
add_item(user,files,type,title
I am writing my first protractor test in Typescript..Here is PageObjectModel class
HomePagePOM.ts
export module HomePage{
export class HomePagePom {
helloTextInput = element(by.model("yourName"));
helloTextDisplay = element(by.css("ng-binding"));
launchPage(url: string): void {
browser.get(url);
console.log("success");
browser.waitForAngular();
}
typeHello(text: string): void {
this.helloTextInput.getWebElement().click();
this.helloTextInput.getWebElement().sendKeys(text);
}
getHelloText() : string {
return this.helloTextDisplay.getWebElement().valueOf();
}
}
}
and my spec class HomePageSpec.ts
import id = require("chai");
import hpp = require("./HomePagePOM");
import HomePage = hpp.HomePage;
var expect = id.expect;
var assert = id.assert;
var should = id.should;
describe("Launch the home page", () => {
var homePagePom = new HomePage.HomePagePom();
it("Launch should be successful", () => {
homePagePom.launchPage("https://www.angularjs.org");
assert.equal("test", "test", "test is success");
});
it("Type Hello Text successfully", () => {
homePagePom.typeHello("Arun");
//assert.equal("test", "test", "test is success");
});
it("Type Hello Text successfully", () => {
assert.equal(homePagePom.getHelloText(), "Hello Arun!", " Hello text typed and retrieved successfully");
});
});
when I run the test, I get this error as below
C:\VisualStudio2013\SampleAutomationPOC\SampleAutomationPOC>protractor conf.js
[23:02:59] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[23:02:59] I/launcher - Running 1 instances of WebDriver
[mochawesome] Generating report files...
Launch the home page
success
1) Launch should be successful
2) Type Hello Text successfully
3) Type Hello Text successfully
0 passing (4s)
3 failing
1) Launch the home page Launch should be successful:
Uncaught InvalidElementStateError: invalid element state: Failed to execute 'replace' on 'Location': '' is not a valid URL.
(Session info: chrome=51.0.2704.103)
(Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any
stacktrace information)
Command duration or timeout: 6 milliseconds
Build info: version: '2.52.0', revision: '4c2593c', time: '2016-02-11 19:06:42'
System info: host: 'ION3076W7LT-3', ip: '10.210.94.178', os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version: '1.8.0_40'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={chromedriverVersion=2.21.371459 (36d3d07f660ff2bc1bf28a75d1
cdabed0983e7c4), userDataDir=C:\Users\ion3076\AppData\Local\Temp\scoped_dir10008_16863}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, hasT
ouchScreen=false, version=51.0.2704.103, platform=XP, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webSt
orageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: 70409fcf7ae2dfd5a1058292d0c30684
I have 2 problem
1. obviously the error
2. when the script executes the angularjs.org website doesn't load all the components completely. Meaning some of the components are blank and the loading looks completed. (the object i am interacting is not shown on the page). So while the script is running i tried to hit the refresh button quickly twice and then the page loaded completely. Manually launching everything looks fine.. Not sure what is causing the issue.
The object I am interacting is unique as far as i know..
Any clues to help me out? enter code here
thanks in advance.
Never mind ..I figured out the answer. For prep reasons i thought of launching the blank browser, I added a line of code browser.get('') in the conf.js under onPrepare() function section. That is causing the issue as ' ' invalid url. I removed it and now it goes through smooth.. long day...and missed to catch the obvious.
Thanks.
I am quite new to selenium IDE.
I try to read from an XML file.
I saw the error on this site but it was not answered (It was stated that the error was with the xml file used, but that seems not to be the case)
The complete error I got is:
[error] Unexpected Exception: [Exception... "The URI scheme
corresponds to an unknown protocol handler" nsresult: "0x804b0012
(NS_ERROR_UNKNOWN_PROTOCOL)" location: "JS frame ::
chrome://selenium-ide/content/tools.js ->
file:///C:/Rommel/user-extensions.js?1447329745072 ::
IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest ::
line 81" data: no]. toString -> function toString() { [native code] },
message -> , result -> 2152398866, name -> NS_ERROR_UNKNOWN_PROTOCOL,
filename -> chrome://selenium-ide/content/tools.js ->
file:///C:/Rommel/user-extensions.js?1447329745072, lineNumber -> 81,
columnNumber -> 0, inner -> null, data -> null, stack ->
IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest#chrome://selenium-ide/content/tools.js
-> file:///C:/Rommel/user-extensions.js?1447329745072:81:5 xmlTestData.prototype.load#chrome://selenium-ide/content/tools.js ->
file:///C:/Rommel/datadriven.js?1447329745073:53:19
Selenium.prototype.doLoadTestData#chrome://selenium-ide/content/tools.js
-> file:///C:/Rommel/datadriven.js?1447329745073:102:2 fnBind/retval#chrome://selenium-ide/content/selenium-core/scripts/htmlutils.js:60:12
ActionHandler.prototype.execute#chrome://selenium-ide/content/selenium-core/scripts/selenium-commandhandlers.js:314:28
._executeCurrentCommand#chrome://selenium-ide/content/selenium-runner.js:306:19
TestLoop.prototype.resume#chrome://selenium-ide/content/selenium-core/scripts/selenium-executionloop.js:78:13
fnBind/retval#chrome://selenium-ide/content/selenium-core/scripts/htmlutils.js:60:12
, location -> JS frame :: chrome://selenium-ide/content/tools.js ->
file:///C:/Rommel/user-extensions.js?1447329745072 ::
IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest ::
line 81
I got it with the selenium IDE command: loadTestData
<tr>
<td>loadTestData</td>
<td>C:\Rommel\test_data_file.xml</td>
<td></td>
</tr>
The XML file is this:
<testdata>
<test employee="1" type="1" startDate="01.01.2013" endDate="01.02.2013" />
<test employee="2" type="1" startDate="01.02.2013" endDate="01.03.2013" />
<test employee="3" type="1" startDate="01.03.2013" endDate="01.04.2013" />
</testdata>
I use the next user extension files:
sideflow.js, include.js, datadriven.js, goto_sel_ide.js.
Somewhere I read that the order of the extension files was important but changing the order did not solve the issue.
If I leave the filename blank the error persists, so my conclusion is that the error is not because of the content of the XML file.
I also tried to get the extension files form different sites, but they all seem to be the same.
Help would be very much appreciated.
Solved: after a day of frustration ... I needed to use the filepath: file:///C:/Rommel/test_data_file.xml
instead of
C:\Rommel\test_data_file.xml
I am trying to use Protractor for our application. Unfortunately, the initial login page is non-Angular so I'm having to handle all the implicit waits with ExpectedConditions. In the below code snippet, the click() is never executed. Instead, the test times out waiting for the next page to show. In the console output (also pasted below) I see the the link was found, but I don't see the subsequent click action.
var signUpLink = element(by.id('sign-up-link'));
var isLinkClickable = EC.elementToBeClickable(signUpLink);
browser.wait(isLinkClickable, 5000).then(function() {
signUpLink.click();
});
var isWidgetVisible = EC.visibilityOf(element(by.id('email')));
browser.wait(isWidgetVisible, 5000, 'Sign Up Page is too slow');
Here's a snippet of the console output:
12:54:17.404 INFO - Executing: [find elements: By.id: sign-up-link])
12:54:18.002 INFO - Done: [find elements: By.id: sign-up-link]
12:54:18.006 INFO - Executing: [is enabled: 0 [[ChromeDriver: chrome on MAC ()] -> id: sign-up-link]])
12:54:18.141 INFO - Done: [is enabled: 0 [[ChromeDriver: chrome on MAC ()] -> id: sign-up-link]]
12:54:18.147 INFO - Executing: [find elements: By.id: sign-up-link])
12:54:18.755 INFO - Done: [find elements: By.id: sign-up-link]
12:54:18.760 INFO - Executing: [is displayed: 0 [[ChromeDriver: chrome on MAC ()] -> id: sign-up-link]])
12:54:18.770 INFO - Done: [is displayed: 0 [[ChromeDriver: chrome on MAC ()] -> id: sign-up-link]]
12:54:18.774 INFO - Executing: [find elements: By.id: sign-up-link])
12:54:18.780 INFO - Done: [find elements: By.id: sign-up-link]
12:54:18.787 INFO - Executing: [is enabled: 0 [[ChromeDriver: chrome on MAC ()] -> id: sign-up-link]])
12:54:18.791 INFO - Done: [is enabled: 0 [[ChromeDriver: chrome on MAC ()] -> id: sign-up-link]]
12:54:18.805 INFO - Executing: [find elements: By.id: email])
12:54:18.815 INFO - Done: [find elements: By.id: email]
Edit - 5/10
I got it to work by adding an explicit wait (gasp!). I don't get why this works. Why does it take so long for the link to get clicked?
var signUpLink = element(by.id('sign-up-link'));
var isLinkClickable = EC.elementToBeClickable(signUpLink);
browser.wait(isLinkClickable, 5000);
browser.driver.sleep(3000); // I give up
signUpLink.click();
My best guess based on what you've shared is that the link becomes clickable while elements above it in the DOM are still rendering. The end result is that the wait condition is satisfied, a click event is scheduled, but before the click can occur new elements are rendered that shift the link elsewhere so that the click doesn't actually hit the link. It sounds far-fetched I know, but I saw something similar happen with webdriver-jvm on a project I was working on. On my project I was lucky enough to have jQuery loaded in the page, so I fixed my problem by executing a $(window).load(); using a JavascriptExecutor before trying to click the button, which ensured that the page was entirely loaded before webdriver continued it's execution. You could try doing something similar if you happen to have jQuery loaded up:
browser.driver.executeScript('$(window).load();').then(function() {
var signUpLink = element(by.id('sign-up-link'));
var isLinkClickable = EC.elementToBeClickable(signUpLink);
browser.wait(isLinkClickable, 5000).then(function() {
signUpLink.click();
});
var isWidgetVisible = EC.visibilityOf(element(by.id('email')));
browser.wait(isWidgetVisible, 5000, 'Sign Up Page is too slow');
});
I have a controller which relies on a service built through ngResource. I am having trouble testing this(although both appear to work like a charm in the actual application). The following is the (sanitized) Controller
MyApp.Controller.MyCarsController = (scope, http, typeService) ->
if scope.context==undefined
scope.ferrari_or_porshe =""
scope.id = ""
else if scope.context=="ferrari"
scope.country_or_pi ="Ferrari"
else if scope.context=="porshe"
scope.country_or_pi ="Porshe"
typeService.index
ferrari_or_porshe: scope.ferrari_or_porshe
id: scope.id
, (response) ->
scope.type = response
scope.loading = false
MyApp.Controller.MyCarsController.$inject = ['$scope', '$http', 'Type']
And this is the Service:
MyApp.MyModule.factory 'Type', ['$resource', ($resource) ->
TypeResource = $resource("/api/types/:ferrari_or_porshe/:id", {},
index:
method: "GET"
isArray: true
)
return TypeResource
]
Finally, some test code:
describe 'MyApp.Controller.MyCarsController', ->
beforeEach module('MyModule')
beforeEach inject ($rootScope, $http, $controller, Type) ->
#scope = $rootScope.$new()
#typeService = Type
#scope.context = undefined
$controller 'MyApp.Controller.MyCarsController', $scope: #scope
describe '#home-page', ->
it 'contains a list of types', ->
expect(#scope.types.length).toBeGreaterThan 0
it "sets instance variables correctly", ->
expect(#scope.ferrari_or_porshe).toBe ""
expect(#scope.id).toBe ""
Which fails with:
No more request expected in helpers/angular-mocks.js on line 889
TypeError: 'undefined' is not an object (evaluating 'this.scope.types.length') in controllers/my_cars_controller_spec.js
By judicious application of console.logs, I have discovered that the issue is that the final callback on response is never reached. TypeResource comes back as [Function].
My questions is:
How do I drive the Jasmine Tests to correctly enter the Service and fetch a response? And is there any way to create direct Unit Tests for Services?
Any and all help is appreciated
The Solution is as follows: for the Service, use $httpBackend which is bundled as part of ngMock:
http://code.google.com/p/google-drive-sdk-samples/source/browse/ruby/app/lib/angular-1.0.0/angular-mocks-1.0.0.js?r=c43c943e32be395b7abca8150deb301d3cbc0dbe
Use this to mock the Rest responses. Since in my case I only cared about verifying that a GET request goes out:
describe 'Type', ->
describe '#index', ->
beforeEach module('MyModule')
beforeEach inject(($httpBackend) ->
$httpBackend.whenGET('/api/types/ferrari/1').respond([])
)
it 'for a ferrari scope', inject((Type) ->
ferrari_or_porsche = 'ferrari'
id = '1'
expect( Type.index('ferrari_or_porsche': ferrari_or_porsche, 'id': id) ).toEqual([ ])
)
And then for the controller, mock the service using jasmine spies and use jasmine.any(Function) to warn of the callback.
describe 'MyApp.Controller.MyCarsController', ->
beforeEach module('myModule')
beforeEach inject ($rootScope, $http, $controller, Type) ->
#scope = $rootScope.$new()
#typeService = Type
#scope.context = undefined
spyOn(#typeService, 'index')
describe '#home-page', ->
beforeEach inject ($controller) ->
$controller 'MyApp.Controller.MyCarsController', $scope: #scope
it 'contains a list of types', ->
expect(#typeService.index).toHaveBeenCalledWith({ ferrari_or_porsche : '', id : '' }, jasmine.any(Function))
it "sets instance variables correctly", ->
expect(#scope.ferrari_or_porsche).toBe ""
expect(#scope.id).toBe ""
Note: I make no claims as to the "canonicalness" of this solution. But it works.
Note: The API endpoints are of course tested extensively elsewhere.