using the element(by.model()) syntax to find a field and input text.
element(by.model('sample_ad.id')).sendKeys('batman');
gets the exception from chromedriver:
Stacktrace:
Error: Timed out waiting for Protractor to synchronize with the page after 11 seconds
at Error (<anonymous>)
==== async task ====
WebDriver.executeScript()
at Protractor.waitForAngular (/Users/jon/dev/project_name/node_modules/protractor/lib/protractor.js:278:22)
at Protractor.findElement (/Users/jon/dev/project_name/node_modules/protractor/lib/protractor.js:427:8)
at Object.elementFinder.(anonymous function) [as sendKeys] (/Users/jon/dev/project_name/node_modules/protractor/lib/protractor.js:62:21)
at null.<anonymous> (/Users/jon/dev/project_name/test/e2e/features/somedirectiveSpec.js:24:39)
at /Users/jon/dev/project_name/node_modules/protractor/jasminewd/index.js:54:12
==== async task ====
at null.<anonymous> (/Users/jon/dev/project_name/node_modules/protractor/jasminewd/index.js:53:12)
at null.<anonymous> (/Users/jon/dev/project_name/node_modules/protractor/node_modules/minijasminenode/lib/async-callback.js:45:37)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Not sure why this is breaking, but Protractor seems very fragile right now... I have no issues using the browser object to find elements, input text, etc...
Any help would be appreciated
EDIT: if I change the line to the following, I am able to interact with the text field.
browser.driver.findElement(protractor.By.id('sample_ad_id')).sendKeys('batman');
hopefully this will help others....
Found this on github (see references link). The issue I believe is a script not returning, thus the sendKeys didn't work. Before interacting with the dom using protractor objects (element, ptor, etc), set this variable:
browser.ignoreSynchronization = true;
The reason the following works is because it doesn't rely on async calls, its just directly interacts with the dom and inserts the keys into the input field.
browser.driver.findElement(protractor.By.id('sample_ad_id')).sendKeys('batman');
The reason my call didn't work (I believe) is because there was an async call that didn't return in time.
element(by.model('sample_ad.id')).sendKeys('batman');
references:
https://github.com/angular/protractor/issues/325
See https://github.com/angular/protractor/blob/master/docs/faq.md#my-tests-time-out-in-protractor-but-everythings-working-fine-when-running-manually-whats-up
for more information on timeouts.
It looks like your test is timing out. The default timeout for protractor is 11 seconds.
Try setting a different timeout for this test:
it('should override timeout', function() {
// Timeout of 30 seconds.
element(by.model('sample_ad.id')).sendKeys('batman');
}, 30000)
You can also override the timeout for all your tests in the protractor configuration file. See this sample config file:
https://github.com/andresdominguez/protractor-meetup/blob/master/protractor-config.js#L19
// Inside the protractor config file.
onPrepare: function() {
// Override the timeout for webdriver.
var ptor = protractor.getInstance();
ptor.driver.manage().timeouts().setScriptTimeout(60000);
}
Related
We have been using useFakeTimers() (sinon v11.x) in many spec files for quite a long time. Recently, we have updated our sinon to 14.x version, now the tests are failing with below error.
TypeError: Can't install fake timers twice on the same global object.
We have tried with createSandbox() also, didn't help.
The issue seems like after Sinon 12.x, not restoring the clock in the spec files, injecting it into global scope which throws the aforementioned error.
So the fix is, call clock.restore() in afterAll() or afterEach() based on whether you used beforeAll() or beforeEach().
So, I encountered this error, for instance, if I had two tests which both used fake timers. You have to call useFakeTimers independently of your sandbox creation.
Fails miserably because reasons
/// Somefile
const superTrialAndErrorSimulator = sinon.createSandbox({
useFakeTimers: true
});
// Some other file
const superTrialAndErrorSimulatorZool = sinon.createSandbox({
useFakeTimers: true
});
If you set fake timers after setting the sandbox, then reset them, it works. Welcome to the trial and error world of sinon.
Works miserably because reasons
const ifOnlyThereWereABetterLibrary = sinon.createSandbox();
before(() => {
ifOnlyThereWereABetterLibrary.useFakeTimers();
});
after(() => {
ifOnlyThereWereABetterLibrary.clock.restore();
});
// Works.
I have a file called defichain.js and am trying to communicate with the defichain blockchain via OCEAN REST API in my project. I am using Node.js version 16.14.2. I am running the .js script with the latest version of truffle.
I already managed to print out the WhaleApiClient object in the console to check its available functions, so at least it is recognizing the client.
Anyways, when I am trying to get the current stats of the DeFi-Chain Blockchain (e.g. number of masternodes), I get TypeError: fn is not a function.
Clearly I am not calling any function named fn here.
const { WhaleApiClient } = require('#defichain/whale-api-client')
const client = new WhaleApiClient({
url: 'https://ocean.defichain.com',
timeout: 60000,
version: 'v0',
network: 'mainnet'
});
console.log(client); // prints client object with all of its categories
console.log(client.stats.get()) // prints Promise { <pending> }
// it seems like something is wrong here :(
client.stats.get().then((data) => {
console.log(data)
})
I am expecting an output in the console something similar to:
{
"data":{
"count":{
"blocks":1831387,
"prices":97,
"tokens":146,
"masternodes":11044
},
"burned":{
"address":156009915.966001,
"fee":237127,
"auction":473292.86501403,
"payback":49335487.46135226,
"emission":82354933.12182175,
"total":288423830.22026604
},
"tvl":{
"dex":874830839.7451664,
"masternodes":956478286.6812595,
"loan":260332219.5450214,
"total":2091641345.9714475
},
"price":{
"usd":4.164032593301086,
"usdt":4.164032593301086
},
"masternodes":{
"locked":[
{
"weeks":0,
"count":7435,
"tvl":655918414.0967871
},
{
"weeks":520,
"count":2859,
"tvl":238099383.6849561
},
{
"weeks":260,
"count":750,
"tvl":62460488.89951629
}
]
},
"loan":{
"count":{
"collateralTokens":6,
"loanTokens":28,
"openAuctions":8,
"openVaults":9915,
"schemes":6
},
"value":{
"collateral":260332219.5450214,
"loan":136835351.84522375
}
},
"emission":{
"masternode":84.5329931,
"dex":64.54739497,
"community":12.45295518,
"anchor":0.05072487,
"burned":92.04027360305092,
"total":253.62434172305092
},
"net":{
"version":2070000,
"subversion":"/DeFiChain:2.7.0/",
"protocolversion":70028
},
"blockchain":{
"difficulty":22297887949.45695
}
}
}
For more information on Ocean REST API, Defichain and its Jellyfish library:
Ocean REST API is a quite unknown project and still in its early stages. Ocean REST API is a global infrastructure project hosted by DeFiChain to simplify building decentralized light applications. Powered by the Jellyfish Ecosystem, Ocean Nodes are globally distributed around the world, any API request is served by the node nearest to the requester with auto fail-over.
https://jellyfish.defichain.com/ocean/
I solved it by myself after a long headache. The error showed following:
TypeError: fn is not a function
at Object.exec (/usr/local/lib/node_modules/truffle/build/webpack:/packages/require/require.js:127:1)
at node:internal/util:360:7
at new Promise (<anonymous>)
at bound exec (node:internal/util:346:12)
at Object.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/exec.js:75:1)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at Command.run (/usr/local/lib/node_modules/truffle/build/webpack:/packages/core/lib/command.js:183:1)
Looking at the first line, I thought that the problem might be in node_modules/truffle/ and has nothing to do with my rest-api calls in the first place.
I found out that truffle exec <example_script> does not properly handle require statements for local node modules in example_script and it was a common bug in 2016 (see:
https://github.com/trufflesuite/truffle/issues/255)
However, deep in the discussion I found an answer from Tim Coulter
"Due to technical reasons, truffle exec in Truffle 2.0 requires your script to output a module that's passed a callback function."
In the original post, he is referring to a post which leads to the documentation site of truffle which doesn't work anymore today.
I found this link here:
https://trufflesuite.com/docs/truffle/getting-started/writing-external-scripts/
In order for external scripts to be run correctly, Truffle expects them to export a function that takes a single parameter as a callback:
module.exports = function(callback) {
// TODO: implement your actions
// invoke callback
callback();
}
You can do anything you'd like within this script, as long as the callback is invoked when the script finishes. The callback accepts an error as its first and only parameter. If an error is provided, execution will halt and the process will return a non-zero exit code.
Protractor hangs completely when trying to get any element property after logging in (idk if it's related to logging in or related just to switching pages).
it("Should get location of main container", async function() {
await LoginPage.validLogin();
// Works and logs in the dashboard
await browser.sleep(3000);
// Get the main container by class name
const container = await element(by.css(".main-container"));
// Logs properly the element functions (as expected)
console.log(container);
console.log(await container.getLocation()); // Hangs here
});
In this case, I'm trying to get the location of the main container element on the page. The first console.log fires and shows properly, while the second hangs completely, so I get the script timeout. Increasing the timeout time doesn't help at all...
I found online that misusing $timeout in AngularJS instead of using $interval may lead to this strange behaviour, but I really can't skim through the entire (very big!) project's codebase to change everything hoping that it just works, not to talk about the external libraries using $timeout.
I have SELENIUM_PROMISE_MANAGER = false; in my Protractor config so I disabled the built-in Control Flow in order to manually manage the promises using async/await, but even if I use the built-in Control Flow without using async/await I get the very same behaviour and error.
I'm using Jasmine as testing framework.
Maybe I'm missing something? Any help would be much appreciated, thanks!
This is caused by the fact that angular is not stable. Have a look at the link below. I found my answer there. When the page you are trying to test is open go to the browser dev tools and type in the console getAllAngularTestabilities(). There are a few properties here that indicate whether angular is ready to be tested. hasPendingMicrotasts needs to be false. hasPendingMacroTasks needs to be false. isStable needs to be true. I put a screenshot below. In my screenshot hasPendingMacrotasks is true and it must be false. So the page I looked at was not ready to be tested.
Failed: script timeout: result was not received in 11 seconds From: Task: Protractor.waitForAngular() - Locator: By(css selector, #my-btn)
Try something like this:
it("Should get location of main container", async function() {
await LoginPage.validLogin();
const container = await element(by.css(".main-container"));
await browser.wait(protractor.ExpectedConditions.presenceOf(container), 5000, 'Element taking too long to appear in the DOM');
await console.log(await container.getLocation());
});
I don't think that getLocation() exists in the Javascript bindings for selenium. I couldn't find it in the source code anyway. So that promise will never return which is why it hangs. But I the you can achieve basically the same thing with getRect():
it("Should get location of main container", async function() {
await LoginPage.validLogin();
const container = await element(by.css(".main-container"));
await browser.wait(protractor.ExpectedConditions.presenceOf(container), 5000, 'Element taking too long to appear in the DOM');
await console.log(await container.getRect());
});
I'm using angular-growl-v2 notifications in my app.
They work ok, the problem comes on my protractor tests. I have to use a TTL (around 6 seconds) as it is a requirement. Then I have the following test:
it('should send a request and notify the user about the result',function(){
detailPage.verifyEmailtButton.click().then(function(){
var expectedDiv = element(by.css('.alert-success'));
expect(expectedDiv).toBeDefined();
});
});
But it is always throwing an error:
NoSuchElementError: No element found using locator: By.cssSelector(".alert-success")
This does not happens when the TLL is -1.
Someone can help here? Thanks in advance.
angular-growl-2 uses $timeout, which doesn't play nicely with protractor: protractor waits for the timeout to end before it completes its sync with angular process.
So by the time it reaches your expect call, the timeout has elapsed and the alert is no longer there. Check out the Waiting for page synchronization section of this doc:
https://github.com/angular/protractor/blob/master/docs/timeouts.md
(This page relates to timeouts, which you don't appear to be experiencing, but since the default timeout is 11 seconds, it could well be that the entire process, including your 6 second TTL, takes place before a timeout happens)
There's a PR to angular-growl-v2 to use $interval instead of $timeout, but its currently waiting for tests:
https://github.com/JanStevens/angular-growl-2/pull/85
Explicitly wait for the alert to be present after clicking the button:
detailPage.verifyEmailtButton.click();
var EC = protractor.ExpectedConditions;
var expectedDiv = element(by.css('.alert-success'));
browser.wait(EC.presenceOf(expectedDiv), 10000, "No alert present");
Good morning,
I am currently learning how to drive Selenium with javascript (using mocha). I created a really basic test that is giving me a lot of trouble at runtime. Whenever I run the test a new instance of chrome is created and the browser displays. When the browser initially comes up it places "data:," in the URL box then proceeds to google.com. I then get the following error back:
$ mocha test
Array
#indexOf()
✓ should return -1 when the value is not present!
Google Search
1) should work
1 passing (2s)
1 failing
1) Google Search should work:
Error: timeout of 2000ms exceeded
at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:157:19)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
Here is the test itself:
var assert = require('assert'),
test = require('selenium-webdriver/testing'),
webdriver = require('selenium-webdriver'),
chrome = require('selenium-webdriver/chrome');
test.describe('Google Search', function() {
test.it('should work', function() {
var chromeOptions = new chrome.Options();
chromeOptions.addArguments(['test-type']);
var driver = new webdriver.Builder().withCapabilities(chromeOptions.toCapabilities()).build();
driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === 'webdriver - Google Search';
});
}, 1000);
driver.quit();
});
});
The error message you get looks like a Mocha timeout to me. The normal way to set a timeout in Mocha is:
it("foo", function () {
this.timeout(value);
...
});
where value is whatever value you want (in ms). A value of 0 turns off Mocha's timeouts. The default is 2000ms.
IF it fail somewhere in particular consistently maybe you should be considering calling driver.Manage().Timeouts().
ImplicitlyWait() doesn't actually wait like a Thread.sleep() does, it just sets the drivers maximum wait time for implicit waits. Just calling it once at the start of your code (with 20 second parameter passed in) is sufficient. Read up on ImplicitlyWait and the WebDriverWait class.
As far as I remember (when I had to used) this is caused because you don't get the response in the expected/by default time.