Test DOM methods in javascript IDE not in browser console - javascript

I am wondering why when using any IDE that support javascript language if you try to get element of HTML page using document.querySelectorAll() or any DOM selector method it will return run time error ReferenceError: document is not defined ?
is the reason that document only defined in browser javascript build in console ?
my problem that I only need to run javascript app on my IDE not on browser console to test it.
if there is any suggested solution please mention it.

What do you mean by run "on my IDE" ?
I think you rather talking about rendering on server side.
Either way, yeah the document exist solely on the browser, if nothing is done to mock it. but there are solutions to mock the document, for example, jsdom :
https://github.com/tmpvar/jsdom
It is useful for example for running unit tests on server side, without browser, to test UI components which require DOM and have some logic.

Finally solution that worked in my case using Nodejs,jQuery and jsdom library as suggested in jony89's answer.
in newer jsdom v10 API I should parse my HTML page into JSDOM constructor to get the result that I expected.
but it's difficult and inconvenient to pass the whole HTML page to JSDOM constructor so I used another simpler way to solve it using older jsdom API and exactly by jsdom.env() method :
https://github.com/tmpvar/jsdom/blob/master/lib/old-api.md
I pass the page url that I want to use DOM methods on it and then print the output on my nodejs IDE:
var jsdom = require("jsdom/lib/old-api.js");
jsdom.env(
"http://www.ammanu.edu.jo/English/Research/Research.aspx",
["http://code.jquery.com/jquery.js"],
function (err, window) {
var $ = window.$;
var a = $("section a");
for(var i = 0; i < a.length; i++){
console.log(a[i].getAttribute("href"));
}
}
);

Related

Kotlin, how can I read a dynamic website as text?

As titled, I'm trying to read the content of sites like this one, which appears to be javascript based.
I tried using plain jdk lib, then jsoup and then htmlunit, but I couldn't get anything useful out of it (I see just the source code or just the title or null):
val url = URL("https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate")
val connection = url.openConnection()
val scanner = Scanner(connection.getInputStream())
scanner.useDelimiter("\\Z")
val content = scanner.next()
scanner.close()
println(content)
val doc = Jsoup.connect("https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate").get()
println(doc.text())
WebClient().use { webClient ->
val page = webClient.getPage<HtmlPage>("https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate")
val pageAsText = page.asNormalizedText()
println(pageAsText)
}
WebClient(BrowserVersion.FIREFOX).use { webClient ->
val page = webClient.getPage<HtmlPage>("https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate")
println(page.textContent)
}
It should be something easy peasy, but I cant see what's wrong
In order for this to be possible, you need something to execute the JS that modifies the DOM.
It might be a bit overkill depending on the use case, and probably won't be possible if you're on Android, but one way to do this is to launch a headless browser separately and interact with it from your code. For instance, using Chrome Headless and the Chrome DevTools Protocol. If you're interested, I have written a Kotlin library called chrome-devtools-kotlin to interact with a Chrome browser in a type-safe way.
There might be simpler options, though. For instance maybe you can run an embedded browser instead with JBrowserDriver and still use JSoup to parse the HTML, as mentioned in this other answer.
Regarding HtmlUnit:
the page has initially no content, all you see is rendered from javascript magic on the client side using one of this spa frameworks.
It looks like there is some feature check in the beginning that figures out the js support in HtmlUnit does not have all the required features and based on this you only get a hint like "Please enable Javascript to use this application".
You can use
page.asXml()
to have a look at the content trough HtmlUnit's eyes.
You can open an HtmlUnit issue on github but i fear adding support for this will be a longer story.

Access Chrome Options in JavaScript (optional: from Galen test)

I am using Galen (a JS tool for testing layout of a HTML page). It is configured from a .js file which can't use ES6 JS :-(
I need to load/amend ChromeOptions from the Chrome driver but I can't figure out how to access it. I see lots of examples of how to set options but when I do so using:
var options = new chrome.Options();
I get an error saying: ReferenceError: "chrome" is not defined
I have tried using require() and load() functions but with the require I get similar not defined errors (ES6 issue I think) and with load I can't seem to point it at a script the works, I've tried:
load("../../npm_modules/selenium-webdriver")
load("../../npm_modules/selenium-webdriver/chrome")
load("chrome")
etc.
It seems that is not the webdriver that Galen is using, but how do I find the one that it IS using?
and is load() what to use to load it?
Galen uses the Rhino JS Engine. Which means that you can directly call Java classes from within the .js file that configures it, thus allowing for an answer like this:
importClass(org.openqa.selenium.chrome.ChromeOptions);
importClass(org.openqa.selenium.chrome.ChromeDriver);
var options = new ChromeOptions();
options.addArguments("--headless");
var driver = new ChromeDriver(options);
Trick is to know how to import the class you need from the Selenium Chrome driver!
Found this on Galen's Google Groups site.
Used the Selenium HQ API, documented on GitHub, for further expansion of what I was doing. HTH.

Most performant way to execute JS within a webpage in Ruby (HtmlUnit, Celerity, PhantomJS, CasperJS ...)

What's the most performant way to execute JS directly after a HTTP request in JRuby? I know about all the test frameworks like HtmlUnit, Celerity, Capybara + PhantomJS == Poltergeist, CasperJS etc. but they're still test frameworks.
What I need is a simple way to execute all JS code which is included in HTML after fetching the URL e.g. by Net::Http.
First of all, it goes with out saying: DON'T DO THIS IN PRODUCTION!
Executing some script that's been pulled from somewhere on the internet is a recipe for disaster. If you're using it as part of your testing infrastructure, it may be of some use but I'd guess that there's a simpler way to solve your problem.
To answer the more general question, here's how you'd initialize a JavaScript engine bundled with JDK 1.6+ (effectively a cut down version of Rhino, although this will change in Java 8 probably):
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
manager = ScriptEngineManager.new
engine = manager.getEngineByName("JavaScript")
bindings = SimpleBindings.new
bindings['x'] = 1
engine.eval("print(x)", bindings)
Getting your engine to evaluate any dependencies like jQuery is left as an exercise to the user. Have a look at the javax.script JavaDoc.
If you need more control over the evaluation environment you'll have to use Rhino directly, or wait for Nashorn...

Running browser javascript unit tests in node

I've got a project that I'd like to move the testing from rhino to nodejs for (rhino simply takes too long to start and load in envjs). This is the current blocker before being able to move forward:
ExampleSingleton = new function () {
var something = someFunction () {/*Does something*/}
$(window).bind('resize', something);
}();
This complains about window not being defined - I don't know how to get the 'window' that I made in the shell (#!/usr/bin/env node) script that I wrote (see below, and pardon the chaos, as I've gotten to that "try anything and everything" point).
var dom = require("jsdom").jsdom()
var window = global.window = dom.createWindow();
global.jQuery = require("jQuery");
global.$ = global.jQuery;
....
require("path/to/file"); //This is where it breaks, before the tests even start
I've tried reading in and eval'ing as well, but that didn't much help and of course the error was masked because it was an anonymous function.
Am I trying to do the impossible here? Or is there a very simple browser friendly thing I can do to get this working?
Have you thought about using PhantomJS instead of node?
PhantomJS is a headless WebKit with JavaScript API. It has fast and
native support for various web standards: DOM handling, CSS selector,
JSON, Canvas, and SVG.
PhantomJS is an optimal solution for fast headless testing, site
scraping, pages capture, SVG renderer, network monitoring and many
other use cases.
Because it is a real browser, you won't need jsdom or envjs. JavaScript continuous testing with QUnit, PhantomJS and Powershell might help you get started.

Using third-party JS libraries in Mozilla Add-On SDK

I'm starting a new project (Firefox add-on) and I'd like to try using behavior-driven development. I particularly like the Jasmine BDD library. However, I can't find a good way how to use a framework such as Jasmine in the Add-On SDK.
One problem is that Jasmine needs setTimeout (and similar) functions to be specified on the global object, whereas Add-On SDK exports those using "timers" module. But let's say I tweak Jasmine to get those object from "timers" (or add the the methods exported by timers to the global object).
The bigger problem is that I don't know how to actually run the tests. There is a test directory generated by the SDK, however, there's no window or document object there to allow me to see the output (and I'd really like to see the fancy HTML output). I guess I could create a content script that would modify the page, but then I can't access (test) the background script.
Have you ever faced this before? Is there any recommended way how to deal with that?
Thanks!
Tomas
You can use the Add-on SDK windows API to open a new window to run your tests in. You should be able to load the Jasmine script(s) with the subscript loader and set window and document to whatever you want in the scope of that subscript:
var windows = require("windows").browserWindows;
windows.open({
url: "about:blank",
onOpen: function(window) {
var script;
var scriptLoader = Cc["#mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
scriptLoader.loadSubScript(subscriptSpec, script);
script["window"] = window;
script["document"] = window.document;
// ... run your tests here by calling script.someFunc() ...
}
});
Update: Further research shows that the browserWindows are actually special wrappers that don't give you access to the content window. You might try getting a window/document from a hidden frame. That's the only way I can see to get access to an HTML document from privileged code.

Categories

Resources