I'm working on a project in IntelliJ that uses PhantomJS and Selenide to automate web browsing activity. To run Javascript commands, we use the executeJavascript() method in our Java code.
We call this method many times in our code to execute the Javascript commands that we want.
For this particular case, we are making a program that should automatically log us into Footlocker.
Code for program:
public Boolean doInBackground() {
WebDriver driver = getWebDriver();
System.out.println("Running Footlocker");
open(account.getEarlyLink()); //opens URL
System.out.println("Running Footlocker");
if (!loggedIn) {
WebDriverRunner.setWebDriver(driver);
$("#guest_welcome_login").shouldBe(visible).click();
$("#login_container").shouldBe(visible);
}
executeJavaScript("$('html').find('iframe').eq(1).contents().find('#login_email').val('%s')", account.getUsername());
executeJavaScript(String.format("$('html').find('iframe').eq(1).contents().find('#login_password').val('%s')", account.getPassword()));
executeJavaScript("$('html').find('iframe').eq(1).contents().find('button.button.cta_button').click()");
$("#member_welcome").shouldBe(visible);
}
When we run the program, none of the executeJavascript() commands are actually executed, but when we run each command one by one in the IntelliJ expression executer (in the debugger), they work.
Anyone know what's happening here?
Did you try to SWITCH into frame?
Typically in Selenium you need to switch into frame/iframe to get access to its elements. Like this:
switchTo(frame(1));
executeJavaScript("$('#login_email').val('%s')", account.getUsername());
Related
I'm working with Selenium WebDriver (3 latest, Chrome driver, 83 latest) in C# (windows10, .net fw 4.6.2). I'm trying to start the IDE recording from within the code of a running automation test, on the open web page, (my intention is to record all the actions being done within the automation test), but with no success.
I'm trying to do it using the IDE extension API (I don't want that the IDE will be actually open during the test, nor do I want it to reopen the page for recording, since it is already open by the automation test)
My final intention is to use the outcome of the IDE recording for something I need.
Here is my C# code:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace IDE
{
class Program
{
static void Main(string[] args)
{
ChromeOptions options = new ChromeOptions();
// Load IDE extension to chrome
options.AddExtension(#"C:\Users\<my user name>\Downloads\extension_3_17_0_0.crx");
IWebDriver driver = new ChromeDriver(options);
// Start IDE recording
((IJavaScriptExecutor)driver).ExecuteScript("chrome.runtime.sendMessage(\"mooikfkahbdckldjjndioackbalphokd\", {uri: \"/record/session\", verb: \"post\", payload: {url: 'https://www.google.com'}});");
driver.Navigate().GoToUrl("https://www.google.com");
driver.Manage().Window.Maximize();
// Do some more actions
// ......
// Stop the IDE recording
((IJavaScriptExecutor)driver).ExecuteScript("chrome.runtime.sendMessage(\"mooikfkahbdckldjjndioackbalphokd\", {uri: \"/record/session\", verb: \"delete\"});");
driver.Quit();
}
}
}
I can see that the IDE extension is loaded, but the "chrome.runtime.sendMessage" is always throwing an exception (no matter what I supply as a value to its parameters) : "Cannot read property 'sendMessage' of undefined". The code I pasted here is just an example. I tried many other variations of "chrome.runtime.sendMessage". All of them threw the same exception.
I've seen a few discussions over the net about that exception in relation to my issue, but they all mention some java script files that have to be changed (manifest, content, etc.), which I'm not sure how to combine their suggestions with my code as it is in C#.
What am I missing here?
Any help will be much appreciated.
Thanks!!!
I am still waiting for anyone who could help. My question is very detailed and well explained. So is the code, that can be easily pasted, as is, to the editor (Just have the relevant refereces and the CRX file in your machine). If I can narrow it to one sentence, it would be: "How do I use the Selenium IDE API from the web driver in C# code?"
Firefox Web Console offers a screenshot helper function:
:screenshot --selector '#element-id' --dpr 1
Probably a silly question, but is it possible to call this function from JavaScript at my website? Say, I have some button and it calls this:
function downloadScreenshot()
{
if(navigator.userAgent.toLowerCase().indexOf('firefox') === -1)
{ alert("Firefox-only"); return; }
eval(":screenshot --selector '#element-id' --dpr 1");
}
If I try to run this I naturally get SyntaxError: expected expression, got ':'.
So is there some way to call Firefox Web Console API (or whatever) from JS and "tell" it to execute the screenshot command?
Firefox Developer Edition 63.0b10 (64-bit).
I reckon, it is not possible. One of the reasons would be that "malicious" scripts at websites could spam your disc with screenshots taken every millisecond.
You can't. Those helper functions are executed in a totally different context then a web page, with totally different privileges. Here the source code: https://searchfox.org/mozilla-central/source/devtools/shared/screenshot/save.js
So from a web page, you don't have access to them.
The only way to have a similar functionality, is create your own add-on that take the screenshot. Then, from your website, you can check if the add-on is installed, and send to it the command to take the screenshot.
I am trying to scrap a website so I use selenium-webdriver.
I've chosen javascript and nodejs as language to teach myself.
The following is a very basic code to understand the behaviour of the tool.
I launch it with the following command line :
node --debug-brk=5858 src/app.js
var chromedriver = require('chromedriver');
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
driver.get('http://www.google.com/ncr');
debugger;
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.findElement(By.name('btnG')).click();
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
driver.quit();
I am using vscode as IDE.
When I press F5, after setting a breakpoint in the code, the breakpoint is hit BUT no browser is opened yet. I click on resume (in VScode), the script finishes, and only then the browser is launched and corresponding commands are executed, my breakpoint being now ignored since it has already been hit.
This has the following consequence : I cannot step by step the selenium webdriver and thus am unable to evaluate the content of a find elements with xpath command.
I am missing Something but fail to see what.
Do I have to add Sleep statements ?
I've seen most people use java but I'd rather stick to javascript if possible.
There are a couple of issues that I can see in your program.
When using javascript to program webdriver, an important concept is that all function calls are asynchronous and return a Thenable or Promise. So you cannot write line by line like in sequential programming.
You need to work this way:
driver.findElement(By.name('q')).sendKeys('webdriver')
.then( function(){
driver.findElement(By.name('btnG')).click();
...
});
See WebDriver's javascript API Documentation here:
https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index.html
In terms of debugging, if you pause in the browser's developer tool and trace there, what you trace is the website program that you are trying to scrape, but not your webdriver program. I use WebStorm to trace my webdriver program.
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.
I need to run an exe file from a html file wrapped into chromium.
I used http://crportable.sourceforge.net to wrap the application into Chromium.
The following code is not working, nothing is actually happening:
function runFile() {
alert('opening file');
w = new ActiveXObject("WScript.Shell");
w.run('C:/Windows/notepad.exe');
return true;
}
before going ahead and tell me that this is a breach of security or that I am an hacker let me explain what I am trying to do. My application run locally (wrapped into chromium) and it need to run an exe file created in Delphi that process a local power point presentation.
I am trying to run notepad.exe just to prove I can run a local file.
Can you help?
Thank you very much
What you're trying to do is not allowed by default. But you can write a C++ method which is available in your Javascript. This C++ method can actually run your application.