Selenium/PhantomJS Can't Find Javascript in Webjars - selenium

I am running a simple log in test using PhantomJS 1.9.8 and Selenium 2.42.2. Everything is setup with maven and I am using embedded Jetty 8.1.14.v20131031.
Before starting jetty I also add all the webjars to org.eclipse.jetty.webapp.WebAppContext#setExtraClasspath
My login.jsp is using webjars to reference jquery.
<script src="webjars/jquery/1.10.2/jquery.js"></script>
When I run my test I get the following error:
Session [81d93a00-9101-11e5-bc34-79a9cbd8ffe4] - page.onError - msg: ReferenceError: Can't find variable: $
If I change the login.jsp to the full URL the test passes.
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
Is it PhantomJS that is having a problem reading from the webjars or is it Jetty not serving them?

The key was to iterate over the webjars and add each as a classpath resource.
//Ensure that webjars are visible as they are packaged in META-INF/resources
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] webjarResources = patternResolver.getResources("classpath*:/META-INF/resources");
String[] resources = new String[webjarResources.length + 1];
for(int i = 0; i < webjarResources.length; i++) {
Resource webjarResource = webjarResources[i];
resources[i] = webjarResource.getURI().toString();
}
//Try to find the webapp source regardless of the current working directory
URL resource = this.getClass().getClassLoader().getResource("app.properties");
String resourcePath = resource.getPath();
String root = resourcePath.substring(0, resourcePath.lastIndexOf("myapp"));
String path = root + "myapp/src/main/webapp";
File webAppDir = new File(path);
resources[resources.length - 1] = webAppDir.getAbsolutePath();
webapp.setBaseResource(new ResourceCollection(resources));

Related

What are cloudflare KV preview_ids and how to get one?

I have a following wrangler.toml. When I would like to use dev or preview (e.g. npx wrangler dev or npx wrangler preview) wrangler asks to add a preview_id to the KV namespaces. Is this an identifier to an existing KV namespace?
I see there is a ticket in Cloudflare Workers GH at https://github.com/cloudflare/wrangler/issues/1458 that tells this ought to be clarified but the ticket is closed with adding an error message
In order to preview a worker with KV namespaces, you must designate a preview_id in your configuration file for each KV namespace you'd like to preview."
which is the reason I'm here. :)
As for larger context I would be really glad if someone could clarify: I see that if I give a value of an existing namespace, I can preview and I see a KV namespace of type __some-worker-dev-1234-workers_sites_assets_preview is generated in Cloudflare. This has a different identifier than the KV namespace pointed by the identifier used in the preview_id and the KV namespace pointed by the identifier I used in preview_id is empty. Why does giving an identifier of an existing KV namespace remove the error message, deploys the assets and allow for previwing but the actual KV namespace is empty and a new one is created?
How do does kv-asset-handler know to look into this generated namespace to retrieve the assets?
I'm currently testing with the default generated Cloudare Worker to my site and I wonder if I have misunderstood something or if there is some mechanics that bundles during preview/publish the site namespace to the scipt.
If there is some random mechanics with automatic mapping, can this be then so that every developer can have their own private preview KV namespace?
type = "javascript"
name = "some-worker-dev-1234"
account_id = "<id>"
workers_dev = true
kv_namespaces = [
{ binding = "site_data", id = "<test-site-id>" }
]
[site]
# The location for the site.
bucket = "./dist"
# The entry directory for the package.json that contains
# main field for the file name of the compiled worker file in "main" field.
entry-point = ""
[env.production]
name = "some-worker-1234"
zone_id = "<zone-id>"
routes = [
"http://<site>/*",
"https://www.<site>/*"
]
# kv_namespaces = [
# { binding = "site_data", id = "<production-site-id>" }
# ]
import { getAssetFromKV, mapRequestToAsset } from '#cloudflare/kv-asset-handler'
/**
* The DEBUG flag will do two things that help during development:
* 1. we will skip caching on the edge, which makes it easier to
* debug.
* 2. we will return an error message on exception in your Response rather
* than the default 404.html page.
*/
const DEBUG = false
addEventListener('fetch', event => {
try {
event.respondWith(handleEvent(event))
} catch (e) {
if (DEBUG) {
return event.respondWith(
new Response(e.message || e.toString(), {
status: 500,
}),
)
}
event.respondWith(new Response('Internal Error', { status: 500 }))
}
})
async function handleEvent(event) {
const url = new URL(event.request.url)
let options = {}
/**
* You can add custom logic to how we fetch your assets
* by configuring the function `mapRequestToAsset`
*/
// options.mapRequestToAsset = handlePrefix(/^\/docs/)
try {
if (DEBUG) {
// customize caching
options.cacheControl = {
bypassCache: true,
}
}
const page = await getAssetFromKV(event, options)
// allow headers to be altered
const response = new Response(page.body, page)
response.headers.set('X-XSS-Protection', '1; mode=block')
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('X-Frame-Options', 'DENY')
response.headers.set('Referrer-Policy', 'unsafe-url')
response.headers.set('Feature-Policy', 'none')
return response
} catch (e) {
// if an error is thrown try to serve the asset at 404.html
if (!DEBUG) {
try {
let notFoundResponse = await getAssetFromKV(event, {
mapRequestToAsset: req => new Request(`${new URL(req.url).origin}/404.html`, req),
})
return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404 })
} catch (e) {}
}
return new Response(e.message || e.toString(), { status: 500 })
}
}
/**
* Here's one example of how to modify a request to
* remove a specific prefix, in this case `/docs` from
* the url. This can be useful if you are deploying to a
* route on a zone, or if you only want your static content
* to exist at a specific path.
*/
function handlePrefix(prefix) {
return request => {
// compute the default (e.g. / -> index.html)
let defaultAssetKey = mapRequestToAsset(request)
let url = new URL(defaultAssetKey.url)
// strip the prefix from the path for lookup
url.pathname = url.pathname.replace(prefix, '/')
// inherit all other props from the default request
return new Request(url.toString(), defaultAssetKey)
}
}
In case the format is not obvious (it wasn't to me) here is a sample config block from the docs with the preview_id specified for a couple of KV Namespaces:
kv_namespaces = [
{ binding = "FOO", id = "0f2ac74b498b48028cb68387c421e279", preview_id = "6a1ddb03f3ec250963f0a1e46820076f" },
{ binding = "BAR", id = "068c101e168d03c65bddf4ba75150fb0", preview_id = "fb69528dbc7336525313f2e8c3b17db0" }
]
You can generate a new namespace ID in the Workers KV section of the dashboard or with the Wrangler CLI:
wrangler kv:namespace create "SOME_NAMESPACE" --preview
This answer applies to versions of Wrangler >= 1.10.0
wrangler asks to add a preview_id to the KV namespaces. Is this an identifier to an existing KV namespace?
Yes! The reason there is a different identifier for preview namespaces is so that when developing with wrangler dev or wrangler preview you don't accidentally write changes to your existing production data with possibly buggy or incompatible code. You can add a --preview flag to most wrangler kv commands to interact with your preview namespaces.
For your situation here there are actually a few things going on.
You are using Workers Sites
You have a KV namespace defined in wrangler.toml
Workers Sites will automatically configure a production namespace for each environment you run wrangler publish on, and a preview namespace for each environment you run wrangler dev or wrangler preview on. If all you need is Workers Sites, then there is no need at all to specify a kv-namepsaces table in your manifest. That table is for additional KV namespaces that you may want to read data from or write data to. If that is what you need, you'll need to configure your own namespace and add id to wrangler.toml if you want to use wrangler publish, and preview_id (which should be different) if you want to use wrangler dev or wrangler preview.

Cordova FileTransfer Plugin error code 1 for image upload

I am trying to take a picture on my phonegap app and then use the FileTransfer plugin to upload it to my server. I am getting error code 1 but there is no other explanation - this is VERY frustrating. I have scoured every piece of documentation and blog known to man with no luck.
I am using a basic LAMP server and it continues to give me an http 500 code. I am 99.9% sure this error is specific to my server because I have tested this with a different web server of mine and the code works fine. Here is the response:
{"code":1,"source":"file:///storage/emulated/0/Android/data/io.cordova.xxappxx/cache/1477607161788.jpg","target":"https://server.com/php/uploadPhoto.php","http_status":500,"body":"\t","exception":"https://server.com/php/uploadPhoto.php"}
Below is my front-end js code:
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
alert(options.fileName);
options.mimeType="image/jpeg";
var params = {};
params.value1 = sessionStorage.getItem("token");
options.params = params;
options.chunkedMode = false;
options.headers = {Connection: "close"};
var ft = new FileTransfer();
ft.upload(imageURI, "https://servername.com/php/uploadPhoto.php", function(result){
console.log(JSON.stringify(result));
}, function(error){
console.log(JSON.stringify(error));
}, options, true);
}
And here is my back-end PHP code that is being called (uploadPhoto.php):
<?php
session_start();
header('Access-Control-Allow-Origin : *');
$new_image_name = "$userId.jpg";
move_uploaded_file($_FILES["file"]["tmp_name"], "/var/img/".$new_image_name);
?>
This ended up being an issue of image size. I was working on this project for a university and their servers have lots of security installed - one of these security configurations had a very small file upload size limit which was blocking the uploads. I discovered this by scanning some of the log files in the /var/log/ directory.

Error: Cannot find module 'libxmljs'

I am trying to parse xml using phantomjs for the following file, documentpreviewer1.js
var webPage = require('webpage');
var page = webPage.create();
var url = "http://xxx/sitemap.xml";
page.open(url, function(status){
if(status != 'success'){
console.log('Unable to access cfc');
}
else
{
var xml = page.content;
var libxmljs = require("libxmljs");
var xmlDoc = libxmljs.parseXml(xml);
var url1 = xmlDoc.get('//urlset/url[0]/loc');
console.log(url1);
}
});
when I run the above code, I get the following error
cmd sudo phantomjs documentpreivewer1.js
Error: Cannot find module 'libxmljs'
phantomjs://bootstrap.js:289
phantomjs://bootstrap.js:254 in require
documentpreivewer1.js:13
:/modules/webpage.js:281
libxmljs is a node.js module. Although phantomjs can be installed through npm (doesn't need to be) it is not a node.js module. It doesn't share any built-in module with node.js (fs seems the same, but is not equal to node.js fs).
You can use some node.js modules in phantomjs (See Use a node module from casperjs for a related question), but it doesn't seem like you could use libxmljs in phantomjs, because it depends on node-bindings which uses fs and path modules. You will have to change the implementation so that all dependencies can be expressed with phantomjs capabilities.
An alternative might be to use phantom-node or spookyjs for a casperjs node.js module.

Unable to load SWF from application storage directory

While publishing my AIR application(CurrentFile), I have also included chatFile.swf with the installation files.
In my AIR settings panel [AIR 3.7 for Desktop], under 'Include Files' I have the following:
CurrentFile.swf
CurrentFile-app.xml
chatFile.swf
Here is the AS3 code in my CurrentFile.swf:
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.Loader;
import flash.filesystem.File;
var chatLoaderWindow:Loader;
function loadchat(m:MouseEvent):void
{
chatLoaderWindow = new Loader();
chatLoaderWindow.contentLoaderInfo.addEventListener(Event.COMPLETE, chatLoadComplete);
chatLoaderWindow.contentLoaderInfo.addEventListener(Event.INIT, chatInitLoad);
chatLoaderWindow.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, chatErrorLoad);
chatLoaderWindow.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, chatHttpStatus);
myclip.chatwindow.addChild(chatLoaderWindow);
var f:File = File.applicationStorageDirectory.resolvePath("chatFile.swf");
chatLoaderWindow.load(new URLRequest(f.url));
tracebox.text = "Chat URL" + f.url;
}
function chatLoadComplete(e:Event):void
{
tracebox.text = "chat loaded";
}
function chatErrorLoad(io:IOErrorEvent):void
{
tracebox.text = "chat IO Error: "+io;
}
function chatInitLoad(i:Event):void
{
tracebox.text = "chat INIT";
}
function chatHttpStatus(e:HTTPStatusEvent):void
{
tracebox.text = "chat Http"+e;
}
myclip.chatbut.addEventListener(MouseEvent.CLICK,loadchat);
/*
Output:
chat IO Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2035" errorID=2035]
EDIT: I figured it out. It was really simple
This is not required:
var f:File = File.applicationStorageDirectory.resolvePath("chatFile.swf");
chatLoaderWindow.load(new URLRequest(f.url));
Insert this:
chatLoaderWindow.load(new URLRequest("app:/chatFile.swf"));
So now my question is:
What is the purpose of File.applicationStorageDirectory.resolvePath?
There are two directories here. One is the "application" directory, where your install files are placed. One is the "application-storage" directory, which is a convenient place to write files to at runtime. To access these directories you can either use the File.resolvePath() function or use the URI-scheme shortcuts, app: or app-storage:. In your initial attempt, you were just looking in the wrong directory for your file.
File.applicationStorageDirectory.resolvePath("somefile.swf").url will equal "app-storage:/somefile.swf"
File.applicationDirectory.resolvePath("somefile.swf").url will equal "app:/somefile.swf"
The application directory is where your app was installed. The app storage directory is a folder your app can save files to.
resolvePath() returns a file object. You can use it for purposes other than getting the cross-platform url for the file location, such as fileObj.exists and fileObj.parent.createDirectory(). fileObj.url is just the url you would use with URLLoader to access the file in a platform-independent manner.

Ckeditor searching for assets in root URI, while it's application is on sub URI

I've spent the past two days trying to fix this bug, but I really don't have anymore ideas or tools to solve it. I wonder if anyone here in stackoverflow can help me.
I'm trying to fix a website source code that uses the ckeditor gem. The ckeditor gem deliver a embedded web text editor. The problem is that the gem does not do it's job when the website is placed on a subdirectory. If the website is placed in the root directory like www.domain.com it works perfectly, but when I place it at a subdirectory, like www.domain.com/website, it does not show up the text editor.
The cause of not showing the editor is that the application try to find the assets of the ckeditor gem at the root directory of the server:
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/config.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/skins/kama/editor.css?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/lang/pt-br.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/embed/plugin.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/attachment/plugin.js?t=C3HA5RM
When the right adress would be www.domain.com/website/assets/ckeditor/config.js?t=C3HA5RM
I've really searched over all the web trying to find the solution for this, but the only few similar situations that I found didn't provided me a solution.
In this Issue, at github, the user jronallo has the exactly same problem than me. But I tried to implement his solution but was not successful.
In this commit, at the ckeditor repository, the bug seems to be fixed, but even having this fix on my gem, (ckeditor 4.0.2 and rails 3.2.2) it keeps missing the assets on SubUri.
I've also tried manipulating the CKEDITOR_BASEPATH and the Ckeditor.relative_url, manually, but not succesfull again.
Does anyone have any idea about how can solve it? I would appreciate very much.
delete in your ckeditor config external plugins.
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/embed/plugin.js?t=C3HA5RM
Failed to load resource: the server responded with a status of 404 (Not Found) http://domain.com/assets/ckeditor/plugins/attachment/plugin.js?t=C3HA5RM
And it's works!
My config:
/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.editorConfig = function( config )
{
// Define changes to default configuration here. For example:
config.language = I18n.locale;
// config.uiColor = '#AADC6E';
/* Filebrowser routes */
// The location of an external file browser, that should be launched when "Browse Server" button is pressed.
config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";
// The location of a script that handles file uploads in the Flash dialog.
config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads in the Image dialog.
config.filebrowserImageUploadUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads.
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
// Rails CSRF token
config.filebrowserParams = function(){
var csrf_token = jQuery('meta[name=csrf-token]').attr('content'),
csrf_param = jQuery('meta[name=csrf-param]').attr('content'),
params = new Object();
if (csrf_param !== undefined && csrf_token !== undefined) {
params[csrf_param] = csrf_token;
}
return params;
};
config.addQueryString = function (url, params) {
var queryString = [];
if (!params)
return url;
else {
for (var i in params)
queryString.push(i + "=" + encodeURIComponent(params[ i ]));
}
return url + ( ( url.indexOf("?") != -1 ) ? "&" : "?" ) + queryString.join("&");
};
// Integrate Rails CSRF token into file upload dialogs (link, image, attachment and flash)
CKEDITOR.on('dialogDefinition', function (ev) {
// Take the dialog name and its definition from the event data.
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
var content, upload;
if ($.inArray(dialogName, ['link', 'image', 'attachment', 'flash']) > -1) {
content = (dialogDefinition.getContents('Upload') || dialogDefinition.getContents('upload'));
upload = (content == null ? null : content.get('upload'));
if (upload && upload.filebrowser['params'] == null) {
upload.filebrowser['params'] = config.filebrowserParams();
upload.action = config.addQueryString(upload.action, upload.filebrowser['params']);
}
}
});
/* Extra plugins */
// works only with en, ru, uk locales
// config.extraPlugins = "embed,attachment";
//for orfografii
config.disableNativeSpellChecker = false;
// config.removePlugins = 'contextmenu';
/* Toolbars */
config.toolbar = 'Mini';
config.toolbar_Mini =
[
['Source','-','Preview'],
['Cut','Copy','Paste','PasteText','PasteFromWord'],
['Undo','Redo','-','SelectAll','RemoveFormat'],
// ['Styles','Format'],
['Subscript', 'Superscript'],
// ['Subscript', 'Superscript', 'TextColor'],
// ['Maximize','-','About'],
['Bold','Italic','Underline'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote']//,
// ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
// ['Link','Unlink','Anchor'], ['Image', 'Attachment', 'Flash', 'Embed'],
// ['Table','HorizontalRule','Smiley','SpecialChar','PageBreak']
];
config.toolbar = 'VeryEasy';
config.toolbar_VeryEasy =
[
['Source','-','Preview'],
['Cut','Copy','Paste','PasteText','PasteFromWord'],
['Undo','Redo','-','SelectAll','RemoveFormat'],
// ['Styles','Format'],
['Subscript', 'Superscript', 'TextColor'],
['Maximize','-','About'],
['Bold','Italic','Underline','Strike'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
// ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
// ['Link','Unlink','Anchor'], ['Image', 'Attachment', 'Flash', 'Embed'],
['Table','HorizontalRule','Smiley','SpecialChar','PageBreak']
];
config.toolbar = 'Easy';
config.toolbar_Easy =
[
['Source', '-', 'Preview'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
['Undo', 'Redo', '-', 'SelectAll', 'RemoveFormat'],
['Styles', 'Format'],
['Subscript', 'Superscript', 'TextColor'],
['Maximize', '-', 'About'],
'/',
['Bold', 'Italic', 'Underline', 'Strike'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Attachment', 'Flash', 'Embed'],
['Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak']
];
config.jqueryOverrideVal = true;
};
I was having issues with ckeditor searching for skins on root dir because i was loading ckeditor.js dinamically after the whole page load.
The solution I've found in this thread
was to set the global var CKEDITOR_BASEPATH before the call to ckeditor.js.