Automatically close PhantomJs after running script - phantomjs

I want to run PhantomJs scripts from my program, but since the scripts may not be written by me, I need to make sure PhantomJs exits after the execution are either completed or fails for any reason (e.g., invalid syntax, timeout, etc). So far, All I've read says you must always include the instruction phantom.exit() for PhantomJs to exit. Is there any way to automatically close PhantomJs after it executes a given script?
Thanks.

Create a file run-javascript.js:
var system = require('system');
try {
for (var i=1; i<system.args.length; i++) {
var scriptFileName = system.args[i];
console.log("Running " + scriptFileName + " ...");
require(scriptFileName);
}
}
catch(error) {
console.log(error);
console.log(error.stack);
}
finally {
phantom.exit();
}
Then to run your file myscript.js:
phantomjs run-javascript.js ./myscript.js
You have to include an explicit path for the myscript.js, i.e. ./myscript.js, otherwise phantomjs will look for the script as a module.
There are three execution scenarios that are handled here:
Successful execution, in which case phantom.exit() is called in the finally clause.
Error in the script being run, in which case the require function prints a stacktrace and returns (without throwing any error to the calling code).
Error running the script (e.g. it doesn't exist), in which case the catch clause prints out the stacktrace and phantom.exit() is called in the finally clause.

Related

Intercept XMLHttpRequest from Greasemonkey script fails

I seek to manipulate the XMLHttpRequest done by a website using Greasemonkey (version 4.9 installed). Interception should be simple (How can I intercept XMLHttpRequests from a Greasemonkey script?) but does not work for me. Maybe things changed with newer versions of Greasemonkey?
I obviously tried the examples in the linked question, but they don't have any effect - nothing printed in the console although I have an console.log(...) in my customised open function.
Next, I gave unsafeWindow a try. It should not be needed. My userscript runs with #grant none and documentation (see here) says my script should run in the content scope.
With unsafeWindow I get an effect but it breaks XMLHttpRequest completely
// ==UserScript==
// #name Test
// #version 1
// #include *
// #run-at document-start
// #grant none
// ==/UserScript==
"use strict";
let realOpen = unsafeWindow.XMLHttpRequest.prototype.open
console.log("Real: " + realOpen)
unsafeWindow.XMLHttpRequest.prototype.open = function() {
console.log("Called for " + this + " with URL: " + arguments[0])
//call original
return realOpen.apply(this, arguments)
};
window.addEventListener ("load", function() {
console.log ("Page loaded");
});
console.log("Unsafe: ", unsafeWindow.XMLHttpRequest.prototype.open.toString())
console.log("Normal: ", XMLHttpRequest.prototype.open.toString())
This gives following output in console:
Real: function open() {
[native code]
}
Unsafe: function() {
console.log("Called for " + this + " with URL: " + arguments[0])
//call original
return realOpen.apply(this, arguments)
}
Normal: function open(method, url) {
// only include method and url parameters so the function length is set properly
if (arguments.length >= 2) {
let newUrl = new URL(arguments[1], document.location.href);
arguments[1] = newUrl.toString();
}
return origOpen.apply(this, arguments);
}
==> Page loaded
As mentioned, function of XMLHttpRequest is broken. When I use the Firefox developer console to have a further look I get this
>> window.XMLHttpRequest.prototype.open
Restricted { }
Any properties set on window (like window.foobar = "foobar") do not exist in console, but those set on unsafeWindow do. I assume this has to do with Greasemonkey's sandboxing.
Why are there two versions of XMLHttpRequest even when I use #grant none? Why is my custom function restricted? Can I avoid that? Why does it work without problems when I install event listener on window?
Next, I gave unsafeWindow a try. It should not be needed. My userscript runs with #grant none and documentation (see here) says my script should run in the content scope.
This is wrong for Greasemonkey 4 as stated in its announcement:
Due to the more limited abilities that the new extension system gives us, we are currently unable to make #grant none scripts work in the same way. Most importantly, they have a different connection to unsafeWindow. For the short term at least, it's a good idea to adopt cloneInto and exportFunction.
See also this other question Firefox doesn't respect Object.defineProperty() from a Greasemonkey script?
This change explain the observations, but no idea why adding listener to window work.

WebDriverWait times out when run through Continuous Integration

I use the following code to check if an element is visible for my automated tests before interacting with them (Selenium/C#).
public bool ElementVisible(IWebDriver driver, IWebElement element, int secondsToWait = 30, bool doNotFailTest = false)
{
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(secondsToWait));
wait.Until<IWebElement>(d =>
{
if (element.GetCssValue("display") != "none" && element.Size.Height > 0 && element.Size.Width > 0)
{
return element;
}
return null;
});
return true;
}
catch (Exception)
{
if (!doNotFailTest)
{
throw;
}
return false;
}
}
The tests that use this method work every time, when I run tests on my PC. However, when I trigger the tests to be run on our build machine from TFS's Continuous Integration, only then does this method time out when called by my tests. Another point that might be worth noting is: this method works on other websites we test (both locally and through the CI). Just not this one website for some reason...
I have tried:
Running the tests locally on the build machine, cutting out the CI = no issue.
Increased the time out several times to greater values = method times out at the greater values.
Added Thread.Sleep wait before the above try/catch block (my reasoning for this stems from an issue I found on Browserstack whereby an AJAX injected element would not be found by this method alone without first adding an arbitrary wait before the WebDriverWait... which doesn't make sense to me because WebDriverWait is apparently the only thing I need to use to find AJAX injected elements (from what I've read anyway)).
As an aside, the reason I've made this method a bool is because not all of my tests should fail if certain elements aren't found. For example, our website rarely has the terms and conditions updated. When it does, a modal is presented to the user when logging in. We've left this as a manual test, but to prevent this modal from breaking the daily runs, we look for it and accept the terms if it's there (suppressing exceptions).
This timeout error relates to an element of the test we do actually want to find, it is the condition to pass our LogIn test by finding an element on our website that is only present when logged in. This element is injected with AJAX.
Better colleagues than me at CI can't pinpoint why this issue is occurring. Theoretically, the trigger from the CI is simply to initiate the test run - it has no other involvement in the running of the tests...?
I have observed that when triggering the test run from the CI to the build machine, when I VPN to the build machine, I expect to see the browser load up and the tests being conducted, but this is not the case. Maybe this is a factor? Perhaps I'm wrong but this behaviour seems like the tests are running on a headless browser? Yet we have not specified any settings to use a headless version of Chrome (v75).
If it was the case that testing through a headless browser throws timeout errors related to AJAX elements, other tests have passed after logging in - using other AJAX injected elements. It is only when any test calls this method, does it time out, when the run is triggered from the CI, on this specific website.
Very confusing!
I created a JavaScript version of the WebDriverWait, added some debugging (Console.Error.WriteLine()) to output the element's computed styles. The display property was 'none'... however, when I log in manually, in Chrome's developer tools, it is 'block'. Weird.
The element I was looking for was a DIV container that has the class 'loggedin'. I instead passed through an element inside this container that would also only be displayed when logged in (a piece of text). This worked.
My WebDriverWait doesn't work with either of the elements, so I have to stick with this JavaScript alternative. One thing to note, however, is that the evaluation of the element's properties takes 5 seconds, so I've omitted setting an interval between checks.
public bool ElementVisible(IWebDriver driver, By locator, int numberOfPolls = 10, bool doNotFailTest = false)
{
bool elementVisible = false;
int pollCount = numberOfPolls;
Thread.Sleep(1000);
while (!elementVisible && pollCount > 0)
{
try
{
// Takes 5 seconds to compute, bear this in mind when setting an interval or increasing the pollCount
elementVisible = (bool)js.ExecuteScript("var display = window.getComputedStyle(arguments[0]).display; var height = window.getComputedStyle(arguments[0]).height; var width = window.getComputedStyle(arguments[0]).width; return (display != 'none' && height != 0 && width != 0);", driver.FindElement(locator));
}
catch (Exception)
{
}
if (elementVisible)
{
break;
}
pollCount--;
}
if (!elementVisible)
{
if (!doNotFailTest)
{
throw new Exception("ElementVisible(): - element not visible.");
}
}
return elementVisible;
}

How do i stop SSIS Script component to process data

i am processing a ragged semicolon delimited file using script component as transformation.
The component is able to process the data and load to oledb destination. But when error is found it should stop processing further. As i am using try catch block the component doesn't fail and continue to process till the end.
Is there any way i could stop the processing further without failing the component/package?
Let me know if any other information/details required?
sample code:
str.split(";");
if(column[0] == "H")
{
col1=Column[3];
}
if(column[0] != "T")
{
try
{
Row.col1=Column[0];
Row.col2=Column[1];
.....
}
catch
{
update the variable to check if we have error in file.
}
}
Thank you for your time.
The general idea will be that you want to use try/catch blocks to ensure the data processing itself doesn't abort. Once you know your script isn't reporting a failure back to the engine, it's a simple process to not call the AddRow()
Pseudocode
foreach(line in fileReader)
{
try
{
// perform dangerous operations here
// Only add row if you have been able to parse current line
Output0Buffer.AddRow();
Output0Buffer.Col1 = parsedContent;
}
catch
{
// Signal that we should break out of the loop
// do not propagate the error
// You might want to do something though so you know you
// have an incomplete load
break;
}
}
If you are looking to just skip the current bad line, you can substitute continue for the break above.
C# loop - break vs. continue
I didn't get any help from anywhere, But as a work around i have placed a return statement in the code. It checks the error variable if it's true then i will return without processing further. But the thing still is it processes the whole file :(. But it works!!!

PDO error handling [duplicate]

This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
From a tutorial on the intertubes I learned a bit about doing PDO queries. The tutorial used try/catch and the queries are basically structured like so:
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $user, $pass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $dbh->prepare("UPDATE users yada yada yadda");
$stmt->bindParam(':param1', $param1, PDO::PARAM_INT);
$stmt->bindParam(':param2', $param2, PDO::PARAM_INT);
$stmt->execute();
}
catch(PDOException $e)
{
echo $e->getMessage();
}
This of course echos mysql errors on the screen. Not that I intend on having bad queries, but I do not like the idea of echoing out errors right on the screen, figuring what if an attacker tries to induce said errors and try to learn something from them.
Is there a better way to do this so that any errors go to a log file instead, or do I in actuality have nothing to fear in this regard since the bound parameters eliminate the risk of any sql injection?
The tutorial is correct in that you want to use try..catch blocks to catch code that will possibly cause an error and bring down whatever you're loading. So, if you have some code that is dependent on this code executing you'd want to include it in your try section. If you absolutely need this code to execute for whatever you're creating to work, then you'll probably want to catch the error and redirect the user to some type of error page.
If you use the php error log function then instead of
echo $e->getMessage();
You can use
error_log($e->getMessage(),0);
to send the error message from PDO directly to your php error log. If you don't know where the error log is, you can check out this link for a couple pointers to it if you're running a *nix system. If you're running windows there should be a config file somewhere that will tell you. Or you can check the php ini file for the location it's pointing to for a surefire way to find the log.
Is there a better way to do this
Yes, sure!
That's apparently wrong way of handling PDO errors this tutorial taught you.
So, just get rid of these try..catch commands - that's all.
This way you'll have PDO exceptions handled the same way as other PHP errors. Thus, in case of query error your script will be halted and error will be logged (if you tell PHP so).
To tell PHP so, you have to set log_errors ini directive to 1
To tell PHP not to show errors on-screen, set display_errors ini directive to 0 (on a development server you may wish to reverse them though)
Well, my answer probably not in the best practice, so please leave it to the last option. But for my case, it works perfectly.
PDO::__construct however will give you an exception anyway no matter what you set in PDO::ATTR_ERRMODE. I don't know why they design it to behave like that.
My way to solve this problem is to create a code area i call it Debug Critical Section (means you need very careful about the codes in the section), any errors in this section will not directly output to user.
Here is the code i made for my framework:
private function doPDOConnect($dbIndex, &$DBInfo, &$error) {
$dbh = null;
$successed = false;
if (!isset($this->connectedDB[$dbIndex])) {
// Enter Critical Section so no error below belowing code will cause error output, but the error still in log though
facula::core('debug')->criticalSection(true);
try {
$dbh = new PDO($DBInfo['Driver'] . ':' . $DBInfo['Connection'] . '=' . $DBInfo['Host'] . ';dbname=' . $DBInfo['Database'], $DBInfo['Username'], $DBInfo['Password'], array( PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING, PDO::ATTR_TIMEOUT => $DBInfo['Timeout'] )); // ATTR_ERRMODE => PDO::ERRMODE_WARNING. or we will cannot get anything even error happens
$dbh->facula_prefix = $DBInfo['Prefix'];
$dbh->facula_index = $dbIndex;
$dbh->facula_connection = $DBInfo; // In order you want to reconnect this specify database after connection lost etc, remove if you worry about the security issue.
$successed = true;
} catch (PDOException $e) {
$error = $e->getMessage(); // If any error, catch it, to &$error.
}
// Exit Critical Section, restore error caught
facula::core('debug')->criticalSection(false);
if ($successed) {
return $this->connectedDB[$dbIndex] = $dbh;
}
} else {
return $this->connectedDB[$dbIndex];
}
return false;
}
So in your case, you may replace my facula::core('debug')->criticalSection to display_errors off/on to handle the error display handler correctly.
For example:
$display_error_status = ini_get('display_errors');
function criticalSection($entered) {
global $display_error_status;
if ($entered) {
ini_set('display_errors', '0');
} else {
ini_set('display_errors', $display_error_status);
}
}

Selenium 2 - checking error messages

I want to check error messages. These error messages appear only when my website encounters a problem.
My problem is that I use findElement in order to check the error message. So when something goes wrong, Selenium finds it, and everything is O.K.
But when it doesn't (meaning - my website is O.K with no problems) - then Selenium indicates that it doesn't find the element, and rises an exception.
Any idea?
you can surround the findElement in a try-catch block, which will do nothing if the element is not found. e.g.
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
//or do nothing
}
}
Take a look at the answer Selenium Webdriver NoSuchElementException
It suggests the following (I've adapted it a bit for your needs) :
List<WebElement> errorElements = driver.findElements(By.id("ERROR_ID"));
if (!errorElements.empty()) {
// Tests your errors
}
1.For this you should design your test case in such a way that you writes code to check error message only when you are sure that you will get error message.
2.But the point is why are you checking for error message when you know that there will be no problem and code will run fine.
3.If you doesn't know that error will occur.. You can place the risky code in try block and write a catch block which will find error message and check it.