Javascript within AppleScript 'missing value' (for clicking button in Safari) - javascript

I have the following AppleScript with Javascript contained:
set buttontext to "Add Option"
set buttonloc to 1
tell application "Safari"
activate
tell window 1
do JavaScript "var buttonTags = document.getElementsByTagName(\"button\");
var searchText = \"" & buttontext & "\";
var found;
for (var i = 0; i < buttonTags.length; i++)
{if (buttonTags[i].textContent == searchText) {
found = buttonTags[i]; break;
}
}
buttonTags[" & buttonloc & "].click();"
end tell
end tell
It compiles fine but upon execution there is no action and I receive a 'missing value' error. It is designed to traverse a web page in Safari and allow a user to specify the button text and rank to be able to click it.
When execute this Javascript directly in Safari's dev console it works, but I need to have it in AppleScript to wrap it into a longer routine.
Advice appreciated!

I have managed to solve this with amending the end of the JS to:
buttonTags[" & buttonloc & "].click();" in current tab

Related

Is it possible to avoid breaking on a debugger statement in Chrome?

I'm trying to reverse engineer a heavily obfuscated JS and one of the tricks the author does is to continuously call the debugger statement from within an anonymous function:
Unfortunately, I cannot right click and Never pause it, because each time the function is called a new anonymous function is spawned. The only way for me to inspect the code with DevTools open is to toggle the Disable all breakpoints button, but that disables my breakpoints too.
Is there any way to disable exclusively all debugger statements in Chrome?
In case there isnt, what could be done to bypass this anti-tampering trick?
Download the offending webworker.js file to your local drive, and use a text editor to replace all occurrences of "debugger" with ";".
Then use a Chrome extension to replace the remote resource with your local modified version.
https://chrome.google.com/webstore/detail/resource-override/pkoacgokdfckfpndoffpifphamojphii?hl=en
FYI: I do not endorse the above extension. It was just the first I found via Google.
This answer is for an old Chrome prior to 2021 where we could hack the internals of devtools itself by using devtools-on-devtools:
undock devtools into a separate window
press the full devtools hotkey - CtrlShifti or ⌘⌥i
paste the following code in this new devtools window console and run it
{
const rx = /\bdebugger\b/y;
const eventSymbol = SDK.DebuggerModel.Events.DebuggerPaused;
const original = [...SDK.targetManager._modelListeners.get(eventSymbol)]
.find(v => v.listener.name === '_debuggerPaused');
const debuggerModel = SDK.targetManager.models(SDK.DebuggerModel)[0];
SDK.targetManager.removeModelListener(
SDK.DebuggerModel,
eventSymbol,
original.listener,
original.thisObject);
SDK.targetManager.addModelListener(
SDK.DebuggerModel,
eventSymbol,
async function({data}) {
if (data._debuggerPausedDetails.reason === 'other') {
const frame = data._debuggerPausedDetails.callFrames[0];
const code = await frame._script.requestContent();
let {columnNumber: x, lineNumber: y} = frame._location;
let pos = 0;
while (y--)
pos = code.indexOf('\n', pos) + 1;
rx.lastIndex = Math.max(0, pos + x);
if (rx.test(code)) {
debuggerModel.resume();
return;
}
}
original.listener.apply(original.thisObject, arguments);
});
}
Notes:
You can save this code as a snippet in devtools to run it later.
To quickly switch docking mode in the main devtools press CtrlShiftD or ⌘⇧D
Theoretically, it's not that hard to put this code into resources.pak file in Chrome application directory. There are several tools to decompile/build that file so just add the code to any script that has something like SDK.DebuggerModel.Events.DebuggerPaused inside. One can even write a tool that does that automatically on Chrome update.
Right-click the in the gutter on the line with the debugger statement and select "Never pause here".

Python selenium shows exception

I am getting an exception while trying to open a new link. I have written python script and I expected it will open new link whenever it meets certain condition but while it meet condition it shows alert popup(while entering my credential, it shows exception) and I don't know how to fix it. Currently I am working on Firefox browser and I also checked previous questions related to this issue, where their issue got fixed by changing the browser from Firefox to IE, but in my case I can't use IE since my base link will not open(support) in IE. Is there any way to fix this one?
Here is my code:
import time
from datetime import datetime
from selenium import webdriver
try:
driver = webdriver.Firefox(executable_path="C:\\Users\\Programs\\Python\\Python36\\Lib\\site-packages\\selenium\\webdriver\\firefox\\geckodriver.exe")
driver.get('https://base_link')
my_id = driver.find_element_by_name('j_username')
my_id.send_keys('1895')
password = driver.find_element_by_name('j_password')
password.send_keys('1895')
ext = driver.find_element_by_name('extension_login_user')
ext.send_keys('4081111895')
sign_in_button = driver.find_element_by_id('signin-button')
sign_in_button.click()
time.sleep(30)
driver.set_window_size(1024, 768)
driver.maximize_window()
ticket_opened = False
window = 0
while True:
if driver.find_element_by_id('state-text').text == 'Not Ready - GMC Work':
time.sleep(1)
if driver.find_element_by_id('state-text').text == "Not Ready - Break":
if ticket_opened is False:
driver.execute_script("$(window.open('child_link'))")
driver.switch_to_window(driver.window_handles[window])
window += 1
continue
else:
ticket_opened = False
else:
continue
else:
continue
except Exception as e:
print('Exception Occurred: ' + str(e))
print('Time and Date: ' + str(datetime.now())[0:19])
Here I am getting the exception (output):
Exception Occurred: Alert Text: None
Message:
Time and Date: 2017-10-19 04:13:39
Kindly help me to fix out this one using python selenium. If we can't fix this one, then kindly suggest me some other tool/way to fix this one.

Is it possible to send a key code to an application that is not in front?

I'm writing a simple Automator script in Javascript.
I want to send a key-code(or key-storke) to an OS X application that is not in front.
Basically, I want to run this code and do my things while the script opens a certain application, write text, and hit enter - all of this without bothering my other work.
I want something like this:
Application("System Events").processes['someApp'].windows[0].textFields[0].keyCode(76);
In Script Dictionary, there is keyCode method under Processes Suite.
The above code, however, throws an error that follows:
execution error: Error on line 16: Error: Named parameters must be passed as an object. (-2700)
I understand that the following code works fine, but it require the application to be running in front:
// KeyCode 76 => "Enter"
Application("System Events").keyCode(76);
UPDATE: I'm trying to search something on iTunes(Apple Music). Is this possible without bringing iTunes app upfront?
It's possible to write text in application that is not in front with the help of the GUI Scripting (accessibility), but :
You need to know what UI elements are in the window of your specific
application, and to know the attributes and properties of the
specific element.
You need to add your script in the System Preferences --> Security
& Privacy --> Accessibility.
Here's a sample script (tested on macOS Sierra) to write some text at the position of the cursor in the front document of the "TextEdit" application.
Application("System Events").processes['TextEdit'].windows[0].scrollAreas[0].textAreas[0].attributes["AXSelectedText"].value = "some text" + "\r" // r is the return KEY
Update
To send some key code to a background application, you can use the CGEventPostToPid() method of the Carbon framework.
Here's the script to search some text in iTunes (Works on my computer, macOS Sierra and iTunes Version 10.6.2).
ObjC.import('Carbon')
iPid = Application("System Events").processes['iTunes'].unixId()
searchField = Application("System Events").processes['iTunes'].windows[0].textFields[0]
searchField.buttons[0].actions['AXPress'].perform()
delay(0.1) // increase it, if no search
searchField.focused = true
delay(0.3) // increase it, if no search
searchField.value = "world" // the searching text
searchField.actions["AXConfirm"].perform()
delay(0.1) // increase it, if no search
// ** carbon methods to send the enter key to a background application ***
enterDown = $.CGEventCreateKeyboardEvent($(), 76, true);
enterUp = $.CGEventCreateKeyboardEvent($(), 76, false);
$.CGEventPostToPid(iPid, enterDown);
delay(0.1)
$.CGEventPostToPid(iPid, enterUp);

Debug output in tests

How do I output some information in Postman tests?
console.log(tv4.error);
tests["Valid Data1"] = tv4.validate(data1, schema);
console.log() seems to be working but I want to output my info into the same panel where my assertions go (for easier correlation):
Just make a fake test that passes:
var jsonData = JSON.parse(responseBody);
tests["id = " + jsonData.id] = true; // debug message
tests["name = " + jsonData.name] = true; // debug message
Reference for the people who just want to use Chrome’s Developer Tools (which will let you see console output and give you many more features)
To enable it
Type chrome://flags inside your Chrome URL window
Search for "Debugging for packed apps" setting
Enable the setting
Restart Chrome
You can access the Developer Tools window by right clicking anywhere inside Postman and selecting "inspect element".
You can also go to chrome://inspect/#apps and then click "inspect"
Reference
I used this, which isn't the prettiest, but it works for what I needed.
tests["your test name here " + data.data.length] = data.data.length > 100;
Piggybacking on the other answers, just define a function in your Postman test code
var print = function(s){
tests[s] = true;
};
then consume it like
print("current value of x: " + x);
Now You have got sth called "Postman Console" To run it please type CTRL + ALT + C
For mor info see here: https://blog.getpostman.com/2016/08/26/the-postman-console/
One of the way is use the tests[""+value].
e.g
http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=Your_API_Key.
Response :
Similar to a previous answer regarding an alternate option: using dev tools. However, if you are using the native app, right clicking to get the dev tools won't work.
Instead,
Head to View in the application menu, and click on "Show DevTools".
In the DevTools window, clicking on the top level Console tab should show the app’s debug logs.
Reference: https://learning.getpostman.com/docs/postman/collection_runs/debugging_a_collection_run

gDBView is not defined and xul

I'm trying to write a Thunderbird extension using XUL, a custom button that accesses the currently shown email message body and does something with it.
Apparently this would be possible using the global variable gDBView, as in the Display Mail User Agent extension:
var msgURI = null ;
if ( gDBView )
{
msgURI = gDBView.URIForFirstSelectedMessage ;
}
if ( msgURI == null )
{
return ;
}
var messenger = Components.classes["#mozilla.org/messenger;1"].createInstance (Components.interfaces.nsIMessenger ) ;
var msgService = messenger.messageServiceFromURI ( msgURI ) ;
Unfortunately if in my extension I replicate the row:
msgURI = gDBView.URIForFirstSelectedMessage ;
I get the following error from the Thunderbird console:
gDBView is not defined
Is there a reason why this happens? And is this the best (and correct) way to access a mail body?
You're probably running your script in the wrong context, as Wladimir correctly guessed. An easy way to check that gDBView exists is, in the menus, to hit Tools > Error Console, then paste top.opener.gDBView, then hit Enter. This returns (for me) [xpconnect wrapped (nsISupports, nsIMsgDBView, nsITreeView)] which means the object indeed does exist.

Categories

Resources