How to send key combination to selenium chromedriver? - node.js

i am using uirecorder to create mocha test cases to test my web program. I want to send some key combination like "Metakey + R". But i couldn't accomplish that.
here is an example of ui recorder generated step:
it('sendKeys: {DOWN}', async function(){
await driver.sendKeys('{DOWN}');
});
this works perfectly. but i couldn't figure out how to send key combinations.
The question is how can i send key combinations like ctrl+a ( holding ctrl and pressing a then leaving ctrl)
SOLUTION THAT I USE:
i just did it like this, and works fine.
await driver.sendKeys('{CTRL}a{CTRL}');

i just did it like this, and works fine.
await driver.sendKeys('{CTRL}a{CTRL}');

You can use ActionSequence class to perform actions in selenium using Node.
For pressing Left control + a you can simulate mouse action like this :
new webdriver.ActionSequence(driver).keyDown(webdriver.Key.LEFT_CONTROL).sendKeys("a").keyUp(webdriver.Key.LEFT_CONTROL).perform();
More Reference :
Reference 1
Reference 2

Using Keys class:
String keypress = Keys.chord(Keys.CONTROL, "a");
driver.findElement(By.locator("value of locator")).sendKeys(keypress);
Using Actions class:
Actions action = new Actions(driver);
action.keyDown(Keys.CONTROL).sendKeys("a").keyUp(Keys.CONTROL).perform();

To anyone who finds this in the future, here is a solution that worked for me:
const {Key} = require('selenium-webdriver');
...
await driver.actions()
.keyDown(Key.SHIFT)
.sendKeys(Key.TAB)
.keyUp(Key.SHIFT)
.perform();

Related

Selenium how to press two different key combinations after starting up the browser

So im trying to load a website with node selenium, and when im at its root, just press two different key combinations, waiting a bit between each other.
So far ive gotten this
const webdriver = require('selenium-webdriver');
const Keys = webdriver.Key
const By = webdriver.By
const driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.firefox()).
build();
driver.get('https://example.com');
//this element is supposed to be some almost root container, but ideally i dont want to select anything, just press the keys.
driver.findElement(By.id('canvas-container')).sendKeys('webdriver', Keys.CTRL + Keys.F5);
driver.findElement(By.id('canvas-container')).sendKeys('webdriver', Keys.CTRL + Keys.F5);
//wait 2-5 sec
driver.findElement(By.id('canvas-container')).sendKeys('webdriver', Keys.CTRL + Keys.SHIFT + Keys.C);
That doesn't work because
Element is not reachable by keyboard
Can someone help with this?
In case you don't want to select anything, just press the keys ActionSequence is what you are looking for!
I'm not really familiar with Selenium on node.js, but from what I have found the syntax is something like this:
let action = new webdriver.ActionSequence(driver);
action.sendKeys(Keys.CTRL + Keys.F5);
action.perform()

JS Puppeteer: enter multiple chars atomically

I'm trying to fill an html form with puppeteer using type. According to the docs:
page.type(selector, text[, options])
...
Sends a keydown, keypress/input, and keyup event for each character in the text.
I have an issue with other events interfering with my typing process. How can I type my text atomically? I.e. with a single keydown event?
you can do, page.keyboard.sendCharacter("text"), which will do something akin to pasting in the text all at once. Make sure to first focus the selector you want to type into.
await page.focus('selector');
await page.keyboard.sendCharacter('text');
I don't know if it fits your needs but if you want to avoid keyboard events you could set directly the input value
await page.evaluate(() => document.querySelector("YOUR_SELECTOR").value = "Puppeteer");
or, if you need just one keydown event, you can trick Puppeteer by setting the value to "almost" what you need
await page.evaluate(() => document.querySelector("YOUR_SELECTOR").value = "Puppetee");
and use type just for the last char
await page.type("YOUR_SELECTOR", "r");

How to get previous scene name in react native router flux

I need to get a previous scene key in componentWillMount using react-native-router-flux to checkout what screen I come back from and make some action on condition. I looked through a lot but haven`t found an answer. Are there any ways to do that ?
You can achieve this via
Actions.prevScene,
which will return the key of the previous scene in your stack.
Its hard to tell, but easier is pass variable when navigating out, like there:
Actions.home({from: 'about'})
now, Home props contain from variable, and you can handle this.
#sftgf's solution should work, but on react-native-router-flux 4.0.0-beta.28, it erroneously returns the current scene for me.
This Gist worked and has the added benefit of getting other scenes on the stack:
import {Actions} from react-native-reouter-flux
export function getPreviousScene (jumpCount = 1) { // if nothing is passed, it defaults to 1
const index = Actions.prevState.routes.length - (jumpCount + 1) // because zero-based index
if (index >= 0) {
return Actions.prevState.routes[index].routeName
}
return 'home'
}

Chrome Bookmarklet which open in new tab with specific action

I want to make a Chrome Bookmarklet which open a new tab with specific action.
To be more exact I want to have a fixed URL like "https://www.blablabla.com/search=" inside the bookmarklet and when I press it, I want a popup window to appear with an input field.
When I type something in the input field and press enter or OK/submit it should "run" the whole link plus my query.
For example, I press the bookmarklet, the input field appears and input the word "test" (without the quotes).
When I press submit the query, a new tab will open with the address of https://www.blablabla.com/search=test as the URL.
How do I do that?
I tried with prompt function but I can't get it work...
My question is a bit similar to How do I get JavaScript code in a bookmarklet to execute after I open a new webpage in a new tab?.
Although it remains unclear what exact issue you encounter, try the following bookmarklet:
javascript:(function() {
var targetUrl = "http://www.blablabla.com/search=";
new Promise (
(setQuery) => {var input = window.prompt("ENTER YOUR QUERY:"); if (input) setQuery(input);}
)
.then (
(query) => window.open(targetUrl + query)
);
})();
If it doesn't work, you should provide the problem description in more detail.
#Shugar's answer is mostly correct, but you don't need the promise.
javascript:(function() {
var targetUrl = "http://www.blablabla.com/search=";
var input = window.prompt("ENTER YOUR QUERY:");
if (input)
window.open(targetUrl + input)
})();
javascript:void(window.open('http://www.URL.com/'+prompt ('Enter your Query:')));
I hope this helps. Works for me and is much simpler code than I see above. (as long as we reach the end result, that is all that matters right?)

How to get the name of the current layout?

symfony getLayout does not seem to work when layout is set via view.yml. Is there anyway to get this within the controller's action class method
I recently needed this. You can do it but you just need to return the entire view.yml contents as an array:
$view_array = sfViewConfigHandler::getConfiguration(array(sfConfig::get('sf_app_config_dir').'/‌​view.yml'));
Just adjust the relative path from sf_app_config_dir (or use another marker) to get what you need.
It's not a trivial task. The view.yml, is not in the "scope" of the action.
Maybe, you can use setLayout in your action rather then in view.yml.
if you can't, for some reasons... you can try this method to reach datas in view.yml:
Is it possible to get a value from view.yml in an action
Execute the following code in the action. It works for both cases, layout set in the action or in the view.yml.
$controller = $this->getContext()->getController();
$view = $controller->getView($this->getModuleName(), $this->getActionName(), 'Success'); // viewName == 'Success' (default)
$layout_name = $view->getDecoratorTemplate(); // e.g expected: layout.php
Let us know if it works for you.

Resources