I have an issue where i am restricted by the version of phantomJS on the server.
When our headless tests run, Im unable to use CustomEvent api in javascript as Phantom does not understand it.
In browser the code works as exepcted:
var event = new CustomEvent("Interval", {
detail: {
type: 'foo',
IntervalId: 1234,
}
});
dispatchEvent(event);
I need to perform the same task, but by using an older method, pre CustomEvent. Is there a way to do this with the detail object intact?
this is what you need a polyfill for CustomEvent: https://gist.github.com/WebReflection/6693661
Related
How would one abstract away the usage of browser's window object when using the Aurelia framework? I would like to avoid direct dependency on the browser when using functionality such as setInterval or addEventListener for example.
Aurelia has something called Platform Abstraction Library which in theory should provide the functionality I am looking for. However, I could not find any documentation about it at the time of writing this question.
Few examples:
import {DOM, PLATFORM, FEATURE} from 'aurelia-pal';
PLATFORM.addEventListener('click', e => ...);
PLATFORM.requestAnimationFrame(() => ...);
let event = DOM.createCustomEvent('foo', { bubbles: true });
DOM.dispatchEvent(event);
let element = DOM.createElement('div');
if (FEATURE.shadowDOM && FEATURE.scopedCSS && FEATURE.htmlTemplateElement) {
...
}
There's no setTimeout / setInterval in the PAL- I think because aurelia doesn't use setTimeout. I've added an issue to get these added.
I am trying to do Chrome extension, that will pretend, that some plugins are installed. I was trying to edit navigator.plugins, but these properties are read-only. I can add new item navigator.plugins[x], but I do not know, how to create new (Plugin, PluginArray or MimeType) objects in navigator.plugins.
Is it even possible ?
Here's an approach that works quite well for spoofing the PluginArray (notice the Object.setPrototypeOf):
(function generatePluginArray() {
const pluginData = [
{ name: "Chrome PDF Plugin", filename: "internal-pdf-viewer", description: "Portable Document Format" },
{ name: "Chrome PDF Viewer", filename: "mhjfbmdgcfjbbpaeojofohoefgiehjai", description: "" },
{ name: "Native Client", filename: "internal-nacl-plugin", description: "" },
]
const pluginArray = []
pluginData.forEach(p => {
function FakePlugin () { return p }
const plugin = new FakePlugin()
Object.setPrototypeOf(plugin, Plugin.prototype);
pluginArray.push(plugin)
})
Object.setPrototypeOf(pluginArray, PluginArray.prototype);
return pluginArray
})()
Console output:
I haven't added the MimeType property yet, but that should be accomplishable in a similar manner.
Feel free to submit a PR in case you flesh this out (I've developed a plugin for puppeteer that's implementing various detection evasion techniques):
https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth
Edit: I've had some spare time and added code to fully emulate navigator.plugins and navigator.mimeTypes here. It even mocks functional methods, instance types and .toString properties, to make them look native and resemble a normal Google Chrome.
Tried cracking it but failed. Apparently Plugin type can't be instantiated manually. It's read-only by specification and Chrome implements it accordingly (source code). As you can see the constructor is not exposed to DOM, so we can't use new Plugin or other methods to instantiate it.
On the other hand you can try injecting the code into webpage via <script> element, for example, that will replace the entire built-in Plugin class with your own implementation and use that fake class to populate navigator.plugins. Ditto for PluginArray.
I use cordova plugin with Application Insight named cordova-plugin-ms-appinsights (https://github.com/MSOpenTech/cordova-plugin-ms-appinsights/blob/master/README.md) and I tried to add my properties to context, that through each request application will send additional info, for example code name of my application.
I tried as below:
appInsights.context.application.codename = "code name app";
appInsights.trackEvent("my event");
and this did not work.
Can I add additional info to context?
There are 2 issues:
1) Cordova plugin seems to use an old version of the JS SDK. You can try to update it manually after it pulls down the old one (take the most recent one from https://github.com/Microsoft/ApplicationInsights-JS/blob/master/dist/ai.0.js)
2) The feature that adds data to ALL telemetry items is not released yet. It was implemented recently - see JS SDK commit on github. You can either wait a bit until it's released or get the latest from master and compile it yourself (and take the result from /JavaScript/min/ai.min.js)
A hacky alternative may be to create a wrapper on top of SDK methods like trackEvent() which adds the data you need (I'm sorry for giving you the JS SDK code equivalent as I haven't used cordova plugin myself):
// this is you implementation of custom data to be attached
// to all telemetry items.
// It needs to return JSON - as it's expected format for custom properties.
// In this specific case you'll create a custom property 'hey' with value 'yo'
var getMyDataJson = function() {
return { hey: "yo"};
}
// this is your wrapper, you'll call it instead of appInsights.trackEvent()
var myTrackEvent = function(data) {
var toBeAttachedToAllItems = getMyDataJson();
appInsights.trackEvent(data, toBeAttachedToAllItems);
}
<...>
// somewhere later you track your telemetry
// this will call your getMyDataJson() function which'll attach
// custom data to your event.
myTrackEvent("tracked!")
I'm working on implementing correct memory management for a native Node.js module. I've ran into the problem described in this question:
node.js native addon - destructor of wrapped class doesn't run
The suggested solution is to bind the destructors of native objects to process.on('exit'), however the answer does not contain how to do that in a native module.
I've taken a brief look at the libuv docs as well, but they didn't contain anything useful in this regard, either.
NOTE: I'm not particularly interested in getting the process object, but I tried it that way:
auto globalObj = NanGetCurrentContext()->Global();
auto processObj = ::v8::Handle<::v8::Object>::Cast(globalObj->Get(NanNew<String>("process")));
auto processOnFunc = ::v8::Handle<::v8::Function>::Cast(processObj->Get(NanNew<String>("on")));
Handle<Value> processOnExitArgv[2] = { NanNew<String>("exit"), NanNew<FunctionTemplate>(onProcessExit)->GetFunction() };
processOnFunc->Call(processObj, 2, processOnExitArgv);
The problem then is that I get this message when trying to delete my object:
Assertion `persistent().IsNearDeath()' failed.
I also tried to use std::atexit and got the same assertion error.
So far, the best I could do is collecting stray ObjectWrap instances in an std::set and cleaning up the wrapped objects, but because of the above error, I was unable to clean up the wrappers themselves.
So, how can I do this properly?
I was also getting the "Assertion persistent().IsNearDeath()' failed" message.
There is a node::AtExit() function that runs just before Node.js shuts down - the equivalent of process.on('exit').
Pass a callback function to node::AtExit from within your add-on's init function (or where ever is appropriate).
The function is documented here:
https://nodejs.org/api/addons.html#addons_atexit_hooks
For example:
NAN_MODULE_INIT(my_exports)
{
// other exported stuff here
node::AtExit(my_cleanup);
}
NODE_MODULE(my_module, my_exports) //add-on exports
//call C++ dtors:
void my_cleanup()
{
delete my_object_ptr; //call object dtor, or other stuff that needs to be cleaned up here
}
In facebook's doc it says
- (void)calendarEventReminderReceived:(NSNotification *)notification
{
NSString *eventName = notification.userInfo[#"name"];
[self.bridge.eventDispatcher sendAppEventWithName:#"EventReminder"
body:#{#"name": eventName}];
}
JavaScript code can subscribe to these events:
var subscription = DeviceEventEmitter.addListener(
'EventReminder',
(reminder) => console.log(reminder.name)
);
But I can never get this work. Should this be sendDeviceEventWithName instead? Also should native module always be singleton?
Currently, no. Please see this issue:
https://github.com/facebook/react-native/issues/394
Changing the example Objective-C to call sendDeviceEventWithName
instead of sendAppEventWithName fixes the problem.
This seems to confirm what you've suggested. There's a pull request waiting to be merged for this:
https://github.com/facebook/react-native/pull/530