I don't know if the issue lies with me or with OS X.
I have this AppleScript:
tell application "Caffeine"
if active then
turn off
else
turn on
end if
end tell
I translated this to this JavaScript
caffeine = Application("Caffeine");
if (caffeine.active)
{
caffeine.turnOff();
}
else
{
caffeine.turnOn();
}
However caffeine.turnOn(); is never executed, no matter how often I run it. If Caffeine is active, it is turned off, otherwise nothing. The AppleScript equivalent runs. caffeine.turnOn(); and caffeine.turnOff(); by itself also run fine. I can't imagine, that JavaScript for OSA is really this broken, that even this doesn't work.
caffeine.active might be a function, which when not called will always be truly:
var my_fn = function() {};
if (my_fn) console.log('my_fn is truly');
Call the function:
var caffeine = Application("Caffeine");
if (caffeine.active()) {
caffeine.turnOff();
}
else {
caffeine.turnOn();
}
A way to check it, is to simply log the value:
console.log(caffeine.active); // function() { .... }
// or using typeof
console.log(typeof caffeine.active); // "function"
Related
I tried to work this code:
var foo=0
window.onmouseup=function(){
foo=1
}
window.onmousedown=function(){
while(foo==0);
console.log("bar")
}
the "bar" is not shown and the browser (I use Edge) stuck there(unable to close the page), I had to use Ctrl+T and then Ctrl+W
I guess the problem is foo==0 is optimized, so it reads from the cache, but I don't know how to avoid it. Or are there other methods?
You could use setInterval() and put the if statement and the rest of the code in there:
var foo = 0
window.onmouseup = function() {
foo = 1
}
window.onmousedown = function() {
var interval = setInterval(() => {
if (foo !== 0) {
clearInterval(interval);
console.log("bar")
}
});
}
Actually, I think the problem is that your while loop will just continue running until it "breaks", or ends the loop. However, foo will always be 1 and never 0 after mouseup, therefore the program gets stuck in the while loop forever, and no other tasks on the browser including the important ones get run.
TL:DR program stuck on while
I'm using Protractor JS. And the site is written in Angular JS.
So I have a toggle switch. And I noticed the value in the toggle switch goes from true to false and
false to true when you switch it off or on.
I am trying create a condition when Protractor visits my page when it sees the toggle switch 'off' it will turn it 'on'. If the toggle switch is already 'on', it will first turn it 'off' then turn it 'on' again.
I came up with this code, but for some reason it is not working:
if( expect(element(By.id('toggle-switch')).element(By.css('[value="false"]')).isDisplayed()) ) {
element(By.id('toggle-switch')).click();
console.log('in the if')
}
else{
element(By.id('toggle-switch')).click();
browser.sleep(3000);
element(By.id('toggle-switch')).click();
console.log('in the else')
}
This code appears to work only for the if statement. For some reason it will never go to the else. Here is the error I'm receiving:
NoSuchElementError: No element found using locator: By.cssSelector("[value=\"false\"]")
So then I tried
.isPresent() instead of .isDisplayed()
I don't receive the above error anymore, but for some reason when using .isPresent() it always goes to the if statement and only runs that, and never the else statement. No errors displayed.
If there is a better way please let me know. This seems very limiting to not be able to create proper conditions in this framework.
Remember that isDisplayed() returns a promise, you can try with:
element(anyFinder).isDisplayed().then(function(result) {
if ( result ) {
//Whatever if it is true (displayed)
} else {
//Whatever if it is false (not displayed)
}
});
isDisplayed() did not work for me. The API may have been changed. isPresent() is my solution:
var logoutButton = element(by.css('[ng-click="log_out()"]'));
logoutButton.isPresent().then(function(result) {
if ( result ) {
logoutButton.click();
} else {
//do nothing
}
});
The problem is that isDisplayed(), as a lot of methods in WebDriverJS/Protractor, returns a promise which by definition is "truthy" which makes it difficult to debug problems like this.
Let's work through an example to get a better understanding.
Imagine, you have the following code, which may look okay at the first glance:
var elm = $("#myid");
if (elm.isDisplayed()) {
// do smth
} else {
// do smth else
}
Now, it has a serious problem. do smth else part will never be reached, since elm.isDisplayed() is not a boolean value - it is a promise. Even if the element is not displayed, you would still have // do smth part executed.
Instead, if you need to check the value of isDisplayed() to use inside a conditional expression, you have to resolve the promise with then() explicitly:
var elm = $("#myid");
elm.isDisplayed().then(function (isDisplayed) {
if (isDisplayed) {
// do smth
} else {
// do smth else
}
});
There is also a way to catch these kind of errors without even running the code - statically with ESLint and eslint-plugin-protractor plugin. There is a relevant rule that watches if certain Protractor methods are used inside if conditions directly.
Here is what it would output for the code above:
$ eslint test.js
test.js
2:1 warning Unexpected "isDisplayed()" inside if condition protractor/no-promise-in-if
Or try this solution implemented from the top of my head, Schedules a command to test if an element is present on the page. If any errors occur while evaluating the wait, they will be allowed to propagate.
function alwaysSwitchOn(element) {
browser.driver.isElementPresent(element).then(function(isPresent) {
if (isPresent) {
isPresent = true;
}
else {
browser.driver.wait(function () {
return browser.driver.isElementPresent(element);
}, 5000);
}
// to fail the test, then uncomment this line
//expect(isPresent).toBeTruthy();
}).then(function () {
if (element.getAttribute('value') === 'OFF') {
element.click();
}
else {
// turn it OFF
element.click();
// turn it back ON
element.click();
}
});
}
fn usage is to keep trying again and again for 5 seconds till it's true. if the element cannot be found within 5 sec then it'll result in an error code; No such an element is found.Note, If the condition is fulfilled before wait (5s) it'll quickly move to then(...).
If you're in 2021 or the following years
Forget about .then(). Do this instead:
it('test case', async () => {
if (await element(anyFinder).isDisplayed()) {
// Whatever if it is true (displayed)
} else {
// Whatever if it is false (not displayed)
}
});
Long ago I've read a lot about javascript coding conventions, and one of the things I wanted to decide was the better way of declaring functions. I finally somehow stuck with the
var func_name = function(){};
version, because it seemed more useful in certain scenarios, but I wasn't really able to find things that wouldn't work the same way between them until now.
I was writing a function that should've returned a new function to be used in a setTimeout command, but I couldn't get it to work properly, and after I reduced the whole thing to this test code:
var test = new function(x) {
return function() {
if (x % 2 == 1) {
console.log('a');
}
else {
console.log('b');
}
x++;
};
};
I happened to try if writing it in the
function func_name(){}
style would help (because I really couldn't see the problem with my code), and interestingly enough this code
function test(x) {
return function() {
if (x % 2 == 1) {
console.log('a');
}
else {
console.log('b');
}
x++;
};
}
seems to be working perfectly.
A weird thing to discover was that after playing a bit around in the console I realized that the first one effectively becomes the function it should generate.
I tested it in Chrome and Firefox too, and I also tried using it this way
var test = new function(x) {
var result = function() {
if (x % 2 == 1) {
console.log('a');
}
else {
console.log('b');
}
x++;
};
return result;
};
but I wasn't able to make it work.
I would be interested in any explanation to this phenomenon and also it fascinates me if there is a way to make this type of function declaration capable of producing functions.
Thanks in advance!
Edit: I don't know how, but somehow that new keyword got there by mistake :D (and even into the third version by that stupid copy-paste laziness of mine.....)
I'm still interested in knowing why the function becomes what it should create though!
Why are you using new? Remove that and it should be fine IMO.
You are using it as if it were a Construtor.
Though valid, can create issues as your current issue.
First, please excuse my bad English. I'm not use to write in English.
I'm using Node.js and i have variables that sometimes get their value from async functions and sometimes by direct assignment (ex:
async(function(data) {
var x= data.something
}; or x = 5;)
the problem is that later on the have shared code which forces me to duplicate the code.
in syncronius scripting i usually do an if.. else statement to seperate the cases and assign. ex:
if(boolivar){
var x = niceFunc();
}
else {
var x = 5;
}
coolFunc(x);
now days im forced to to this:
if(boolivar){
niceFUnc(function(X){
coolFunc(X);
}
}
else{
var x = 5;
coolFunc(X);
}
does someone has an idea how to solve my problem?
I thought about forcing the async function to be sync but:
a. i dont know how
b. it kind of ruins the whole point
I would do it essentially as you have, except that I would abstract the sync/async calls so that it doesn't make any difference to the code that's using it what's really happening behind the scenes (ignore the bad function names; I have no idea what your code does):
function doNiceFunc(boolivar, callback) {
if (boolivar) {
niceFUnc(function(x) {
callback(x);
});
} else {
callback(5);
}
}
Now doNiceFunc appears the same in both cases from the outside:
doNiceFunc(boolivar, function(x) {
coolFunc(x);
});
I've used this exact pattern in a library that retrieved data that was sometimes immediately available and other times had to be retrieved from the network. The users of this library didn't have to care which was the case at any given time, because the call looked the same in both situations.
I tend to use this lib node-sync
var sync = require('sync');
sync(function(){
var result = query.sync(query, params);
// result can be used immediately
})
So I recently decided to start learning JavaScript. I come from only knowing VB.NET for programming knowledge and HTML & CSS for design. Anyway, scrap.tf is a website for TF2 banking which makes things automatic. I am planning to write a basic Chrome plugin, and I want to be able to if the button is clicked, this function will happen. I've got this all set up but when the button's clicked, it only takes me to scrap.tf/hats, EnQueueHatBank(); is the JS command they use there to join the queue. This even never fires unless I type it in after I'm on the site. Do I need to wait for it to fire?
if (location.href === 'http://scrap.tf/hats')
{
EnQueueHatBank();
}
else
{
window.location.href='http://scrap.tf/hats';
EnQueueHatBank();
}
You need to correct the comparison to use two equal signs.
if (location.href == 'http://www.scrap.tf/hats')
{
EnQueueHatBank();
}
Once you end up with tools like jslint, javascript even offers a === operator, which does type checking, too (checks if both sides are strings, as in this example).
I think this talk of = vs == is missing the point. You're changing window.location before you call EnQueueHatBank, so you navigate to a new page before the function is ever called. That's what's stopping it from running. So the first thing you need to do is:
Call EnQueueHatBank first.
if (location.href === 'http://www.scrap.tf/hats') {
EnQueueHatBank();
} else {
EnQueueHatBank();
window.location.href='http://www.scrap.tf/hats';
}
Clean up the code a little, because the structure is a little awkward. You're calling EnQueueHatBank either way, so there's no need for it to be in the if statement:
EnQueueHatBank();
if (window.location.href !== 'http://www.scrap.tf/hats') {
window.location.href = 'http://www.scrap.tf/hats';
}
Finally, remember that http://www.scrap.tf/hats/ probably goes to the same place as http://www.scrap.tf/hats, not to mention https://www.scrap.tf/hats?foo=bar and so forth. You'd be better off with a less-strict test:
EnQueueHatBank();
if (window.location.href.indexOf('://www.scrap.tf/hats') > -1) {
window.location.href = 'http://www.scrap.tf/hats';
}
EDIT: Based on your comment, you will need to do this:
if (window.location.href.indexOf('://www.scrap.tf/hats') > -1) {
EnQueueHatBank();
}
else {
window.location.href = 'http://www.scrap.tf/hats';
}
This will only work if your program runs again after navigating to scrap.tf/hats, so make sure it runs every time you load a new page.
For security reasons, you cannot initiate code on one page and have it continue after you've navigated somewhere else. You'll have to call EnQueueHatBank from the page it's meant to run on.
You should use comparison === operation, but you did an value assignment =.
if (location.href === 'http://www.scrap.tf/hats')
{
EnQueueHatBank();
}
else
{
window.location.href='http://www.scrap.tf/hats';
EnQueueHatBank();
}