I am working on tests using the selenium IDE extension for chrome and I have basically the same problem as in this question Access JavaScript variables with Selenium IDE
Using this.browserbot.getUserWindow() didn't work at all to get my defined variable and as the question I mentioned is 8 years old, I was wondering if there weren't some updates I missed.
I also looked at the recent documentation https://www.selenium.dev/selenium-ide/docs/en/api/commands and I couldn't find the assertEval command they mention in the question.
I am wondering if the run script command is there for that purpose.
To summarize:
Assuming that I defined an array in the window variable like this window.data=['hello', 'world'] what would be the correct syntax to fetch it during my test?
What is the difference between those two commands? execute script and run script
Is there a more detailed documentation about how to get along with js? I couldn't find where the this.browserbot variable came from.
I will attempt to help on this one as I've used Arrays in IDE. Array creation is done in JS, but there's different ways it's stored in JS and in Selenium and then manipulated upon. To answer point 2, Execute Script is what i always as it calls JS but then completes it in the IDE framework, e.g. can store it in Selenium. Run Script only does it in JS and does not return a log with IDE. To answer point 1 and the whole question:
Method 1
To create a Selenium IDE array, use the JS execute script command and that will enable storing as a Selenium IDE variable only, here's a basic version of that:
Command: execute script
Target: return ["hello","world"]
Value: myArray
To check this, add a 2nd command to check the Selenium variable is correctly stored and displays right result in the IDE log:
Command: echo
Target: ${myArray}
Method 2
If you already have an array defined in JS, e.g. let myJSArray = ["hello", "world"] or window.myJSArray = ["hello", "world"], and it's defined in the window that Selenium already has open, then you can store that in Selenium using:
Command: execute script
Target: return myJSArray | Target: return window.myJSArray
Value: myArray
Then double check it's worked by using the same echo command above
Method 3
If you haven't got the window open and you want to store the variable both in JS and in Selenium, then
Command: execute script
Target: return myJSArray = ["hello","world"] | Target: return window.myJSArray = ["hello","world"]
Value: myArray
Then again use the echo command to check it's worked.
In summary - Method 1 stores the array in Selenium only (using JS to achieve it), Method 2 stores an already stored JS variable in the open window to Selenium, Method 3 stores the variable both in JS window and Selenium.
Depending on the method used, you can then do asserts on the variable (JS one or Selenium one) or even use them in If/Else, loops or general JS functions. If you are using the Selenium variable for any JS scripts of if/else etc, you need to add the ${} to it, if using the JS variable then can call it without the dollar. Example of an Assert using Method 3 for both the Selenium myArray variable or the JS myJSArray variable:
Command: execute script
Target: return myJSArray = ["hello","world"]
Value: myArray
//Now have 2 variables, 1. myJSArray that the browser can use; and 2. myArray that Selenium can use. Below to assert either variable contains the array item "world":
Command: execute script
Target: return ${myArray}.includes("world")
Value: myArrayIncludesWorld
Command: assert
Target: myArrayIncludesWorld
Value: true
Command: execute script
Target: return myJSArray.includes("world")
Value: myJSArrayIncludesWorld
Command: assert
Target: myJSArrayIncludesWorld
Value: true
Related
I want to want pass multiple arguments in mvn command and and that should be read in karate-config.js file.
e.g: mvn test -DargLine="-Dkarate.env='gdcStaging', -Dkarate.source='false', -Dkarate.natco='gdc'"
I didn't want to declare any .prop files, want to get these values at run time.
Below prop. are defined to read these arguments but unable to achieve from this:
var environment = karate.env;
var natco = karate.properties['karate.natco'];
var isLocal = java.lang.System.getenv('karate.source');
I need help to achieve this
karate-version=0.9.0
I had also referred to this link :Pass additional parameters to karate-config.js via command line via Maven
but not worked
Instead of using argLine try passing it directly,
mvn test -Dkarate.env=gdcStaging -Dkarate.source=false -Dkarate.natco=gdc
I suggest not to use karate. as a prefix to your arguments other
than karate.env, instead try using your application name.
eg,
-Dmyapp.source=false
coming to the karate-config.js
var natco = karate.properties['myapp.source']
This should work.
my conftest file for my appium/python test framework looks like:
#pytest.fixture()
def setup(request):
desired_caps = {
...
}
request.cls.driver = webdriver.Remote(
command_executor= "https://"blah.com",
desired_capabilities= desired_caps
)
yield request.cls.driver
request.cls.driver.quit()
And what I am trying to do is be able to access pytest results from within the 'yield' section, and send a pass/fail result to BrowserStack using the command:
driver.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"passed", "reason": "All elements located and assertions passed!"}}')
The problem is, the only method I know to access the pytest results utilizes a hook in conftest, i.e:
#pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
result = outcome.get_result()
if result.when == "call" and result.passed:
do_something
if result.when == "call" and result.failed:
do_something_else
But how do I integrate these too? In other words, how can I take the result from the hook to get the test result, and then use the driver instance from the setup to run the execute_script command. Everything I have tried leads to issues with not being able to access the Appium driver instance. Please help!!
Update:
I have achieved this by using a global variable in the hook to save the result, and then in the fixture I use this data to send the corresponding message, but I know this is not ideal. So the question remains, how can I store a variable from the hook in conftest that gets the pytest result, and pass that to the yield section of the setup fixture?
I'm trying to check which browser we're running tests on, and then skip a test/fixture based on the result (as mentioned in this TestCafe Issue).
import { t } from 'testcafe';
fixture `test`
.page('https://testcafe.devexpress.com')
if (t.browser.name.includes('Chrome')) {
test('is Chrome?', async () => {
console.log(t.browser.name);
await t.expect(t.browser.name.includes('Chrome').ok();
});
} else {
test.skip('is Chrome?')
};
Results in...
ERROR Cannot prepare tests due to an error.
Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead.
Is there any way I can call the testObject (t) outside of the test?
I don't have a solution to exactly your question. But I think it's better to do it slightly differently, so the outcome will be the same, but the means to achieve it will differ a bit. Let me explain.
Wrapping test cases in if statements is, in my opinion, not a good idea. It mostly clutters test files so you don't only see test or fixture at the left side, but also if statements that make you stop when reading such files. It presents more complexity when you just want to scan a test file quickly from top to bottom.
The solution could be you introduce meta data to your test cases (could work well with fixtures as well).
test
.meta({
author: 'pavelsaman',
creationDate: '16/12/2020',
browser: 'chrome'
})
('Test for Chrome', async t => {
// test steps
});
Then you can execute only tests for Chrome like so:
$ testcafe --test-meta browser=chrome chrome
That's very much the same as what you wanted to achieve with the condition, but the code is a bit more readable.
In case you want to execute tests for both chrome and firefox, you can execute more commands:
$ testcafe --test-meta browser=chrome chrome
$ testcafe --test-meta browser=firefox firefox
or:
$ testcafe --test-meta browser=chrome chrome && testcafe --test-meta browser=firefox firefox
If your tests are in a pipeline, it would probably be done in two steps.
The better solution, as mentioned in one of the comments in this question is to use the runner object in run your tests instead of the command line. Instead of passing the browser(s) as a CLI argument, you would pass it as an optional argument to a top-level script.
You would then read the browser variable from either the script parameter or the .testcaferc.json file.
You would need to tag all tests/fixtures with the browser(s) they apply to using meta data.
You then use the Runner.filter method to add a delegate that returns true if the browser in the meta data is equal to the browser variable in the top level script
var runner = testcafe.createRunner();
var browser = process.env.npm_package_config_browser || require("./testcaferc.json").browser;
var runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => {
return fixtureMeta.browser === browser || testMeta.browser === browser ;
}
I have a basic function in BeanShellSampler.bshrc at Jmeter 4.0
String getMyString(String strParam) {
return "MyString: "+strParam;
}
I called in BeanShell Sampler as below
String N = "123123";
log.info("${__BeanShell(getMyString("${__V(Var${N})}"),)}");
When I run Sampler output is somthing like that.
2018-06-18 15:25:40,080 INFO o.a.j.u.BeanShellTestElement: MyString: Var${N}
How can I set string variable to my function?
I read function articles in Jmeter web site
Thank you.
Add the next line to user.properties file:
beanshell.sampler.init=BeanShellSampler.bshrc
Amend your code to look like:
String N = "123123";
log.info(getMyString(N));
That's it, you should get MyString: 123123 in jmeter.log file
Be aware that starting from Jmeter 3.1 it is recommended to use Groovy for all forms of scripting as Groovy performance is much better comparing to Beanshell so consider taking the following steps instead:
Create a file, i.e. foo.groovy in "bin" folder of your JMeter installation and put your function there:
String getMyString(String strParam) {
return "MyString: " + strParam;
}
Add the next line to user.properties file:
You should be able to refer your custom code from __groovy() function like:
${__groovy(log.info(getMyString("123123")),)}
functions can be used anywhere in the Test Plan
For each BeanShell Program type there are different beanshell.*.init properties defined in bin/user.properties
beanshell.function.init=BeanShellFunction.bshrc
beanshell.preprocessor.init=BeanShellSampler.bshrc
beanshell.postprocessor.init=BeanShellSampler.bshrc
beanshell.assertion.init=BeanShellFunction.bshrc
Hence the same function which needs to be called from any program(preprocessor, postprocessor, etc) we need to copy the function to every .bshrc file OR use same .bshrc file for every program init property.
In your case if you are using local string variable N and passing it along with the script. If you use ${Variable} there must be a JMeter variable defined so that JMeter can pick its value. To do that you can use vars.put , write N value to JMeter variables and use ${N} .
I have defined Var123123 value as FinalValue as shown below
And 2 beanshell samplers one is to put String variable N to Jmeter variable and one is beanshell script as shown below
You can see in the log its printed VAR123123's value which is FinalValue
The reason why i took 2 beashell samplers is if i write N to JMeter variables and use it in same script its not updating N value until the sampler executed..
References :
Configuring JMeter
JMeter Beanshell
Please let me know if it helps
I'm running tests with protractor, but it seems impossible to access the JS 'window' object. I even tried adding a tag in my html file that would contain something like
var a = window.location;
and then try expect(a) but I couldn't make it work, I always get undefined references...
How should I process to access variables that are in the browser scope ?
Assuming you are using a recent version of Protractor, let's say >= 1.1.0, hopefully >= 1.3.1
Attempting to access Browser side JS code directly from Protractor won't work because Protractor runs in NodeJS and every Browser side code is executed through Selenium JsonWireProtocol.
Without further detail, a working example:
browser.get('https://angularjs.org/');
One-liner promise that, as of today, resolves to '1.3.0-rc.3'
browser.executeScript('return window.angular.version.full;');
You can use it directly in an expect statement given Protractor's expect resolves promises for you:
expect(browser.executeScript('return window.angular.version.full;')).
toEqual('1.3.0-rc.3');
Longer example passing a function instead of a string plus without expect resolving the promise for you. i.e. for more control and for doing some fancy thing with the result.
browser.driver.executeScript(function() {
return window.angular.version.full;
}).then(function(result) {
console.log('NodeJS-side console log result: ' + result);
//=> NodeJS-side console log result: 1.3.0-rc.3
});