Reputation: 2099
I've got an Angular site that loads (https://x.y.com/) and immediately redirects to (https://x.y.com/#/) [as an example] My initial solution was to load up Protractor per its instructions and run it from there. After this failed, however, I took the basic selenium webdriver tutorial from the selenium site and tried to run it as well. The same error occurred, so I can only assume it's a WebDriver issue.
My protractor script is pretty simple:
login spec.ts:
import {browser, element, by, ExpectedConditions} from 'protractor';
import {get} from "selenium-webdriver/http";
describe('login NOTTHISONE, ##site_location## / ##username## / ##password##', function(){
it('should login and get a token, then be able to see the site.', function(){
var EC = ExpectedConditions;
let siteLocation = '##site_location##';
browser.waitForAngularEnabled(false);
browser.get(siteLocation);
blowser.sleep(60000);
});
});
protractor.conf.js:
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'AWRONGURL',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
The architecture of the page is such that a loading screen (non-angular) is displayed while the angular app loads. Then, once the page is loaded the angular site is enabled.
The problem is that when I load the site in Protractor, I get Javascript errors, as follows:
ERROR TypeError: Cannot read property 'sendMessage' of undefined
at new l (main.385b4b24313957c18fd6.js:1)
at _a (vendor.9256f6b56fd7db28f00b.js:1)
at va (vendor.9256f6b56fd7db28f00b.js:1)
at Ja (vendor.9256f6b56fd7db28f00b.js:1)
at za (vendor.9256f6b56fd7db28f00b.js:1)
at Object.hs [as createRootView] (vendor.9256f6b56fd7db28f00b.js:1)
at e.create (vendor.9256f6b56fd7db28f00b.js:1)
at e.create (vendor.9256f6b56fd7db28f00b.js:1)
at t.bootstrap (vendor.9256f6b56fd7db28f00b.js:1)
at vendor.9256f6b56fd7db28f00b.js:1
sendMessage is a function in my Angular app. So something is.... Odd here. When I change waitForAngularEnabled to true, Angular tells me I don't have an Angular page, (because of the loading screen) but when I change it to false, it causes this error. Should I add something to the loading page to calm Protractor down? Is there a simple solution to this that does not involve setting up a long series of callbacks?
Question, though: is this related to me attempting to run Protractor against a remote server? I'd assumed that since I was running Protractor through a web browser I could point it at any server I liked. If this is not the case, that might be why the JavaScript can't be found.
Edit including my Python script:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
# Create a new instance of the Chrome driver
driver = webdriver.Chrome(executable_path=r'C:\Program Files\chromedriver\chromedriver.exe')
# go to the google home page
driver.get("https://my.testsite.com")
# the page is ajaxy so the title is originally this:
print (driver.title)
# find the element that's name attribute is q (the google search box)
inputElement = driver.find_element_by_id("username")
# type in the search
inputElement.send_keys("cheese!")
# submit the form (although google automatically searches now without submitting)
inputElement.submit()
try:
# we have to wait for the page to refresh, the last thing that seems to be updated is the title
WebDriverWait(driver, 10).until(EC.title_contains("cheese!"))
# You should see "cheese! - Google Search"
print (driver.title)
finally:
driver.quit()
Upvotes: 0
Views: 493
Reputation: 2099
Okay, so there seem to have been two things wrong with my approach. A co-worker went through and rebuilt everything from scratch, :
I was trying to run Protractor against a remote server without a Selenium WebDriver server running on that server. This was a mistake, although I'm not very happy about needing to do this in the first place.
I wasn't using 'jasmine2' in the protractor.conf.js settings, and apparently this was necessary for the way he had put together my angular project.
Just putting this out there in case it helps someone else.
Upvotes: 0
Reputation: 1588
Put your login statements inside browser.wait
function:
browser.wait(EC.visibilityOf(element(by.id("mat-input3"))),60000).then(() => {
browser.driver.findElement(by.id('mat-input3')).sendKeys(username);
browser.driver.findElement(by.id('mat-input4')).sendKeys(password);
browser.driver.findElement(by.xpath("//*[contains(text(), 'SIGN IN')]")).click();
});
Upvotes: 1