Watson Virtual Agent - added javascript to page, now what? - watson-virtual-agent

I followed the instructions to get my bot id, my ibm key/secret and inserted the javascript into my website. I run the site and nothing happens. What do I need to do to see the virtual agent show up on the page?
I followed these instructions to get up and running: https://www.ibm.com/blogs/watson/2016/09/introducing-watson-virtual-agent/?__prclt=run4xzrj
Used this page to get my botid: https://developer.ibm.com/api/view/id-339
I don't see any errors in my site console.
Code included:
<script src='https://dp1-bot-chat.mybluemix.net/IBMChatClient-v1.1.0.js'></script>
<script>
IBMChat.init({
el: 'ibm_chat_root',
baseURL: 'https://api.ibm.com/virtualagent/run/api/v1',
botID: '___mybotid___',
XIBMClientID: '__myclientid____',
XIBMClientSecret: '___mysecret____'
});
</script>

If your site doesn't show a box, it may be caused by a missing root element. Make sure that you have an HTML tag on your site that has an ID matching the value of el (in this case, ibm_chat_root).
If you want to, you can also directly pass an element object:
IBMChat.init({
el: document.getElementById('my-element-id')
});

Related

How to fill login prompt with Webdriver IO?

I'm working on a CLI with OCLIF. In one of the commands, I need to simulate a couple of clicks on a web page (using the WebdriverIO framework for that). Before you're able to reach the desired page, there is a redirect to a page with a login prompt. When I use WebdriverIO methods related to alerts such as browser.getAlertText(), browser.sendAlertText() or browser.acceptAlert, I always get the error no such alert.
As an alternative, I tried to get the URL when I am on the page that shows the login prompt. With the URL, I wanted to do something like browser.url(https://<username>:<password>#<url>) to circumvent the prompt. However, browser.url() returns chrome-error://chromewebdata/ as URL when I'm on that page. I guess because the focus is on the prompt and that doesn't have an URL. I also don't know the URL before I land on that page. When being redirected, a query string parameter containing a token is added to the URL that I need.
A screenshot of the prompt:
Is it possible to handle this scenario with WebdriverIO? And if so, how?
You are on the right track, probably there are some fine-tunings that you need to address to get it working.
First off, regarding the chrome-error://chromewebdata errors, quoting Chrome DOCs:
If you see errors with a location like chrome-error://chromewebdata/
in the error stack, these errors are not from the extension or from
your app - they are usually a sign that Chrome was not able to load
your app.
When you see these errors, first check whether Chrome was able to load
your app. Does Chrome say "This site can't be reached" or something
similar? You must start your own server to run your app. Double-check
that your server is running, and that the url and port are configured
correctly.
A lot of words that sum up to: Chrome couldn't load the URL you used inside the browser.url() command.
I tried myself on The Internet - Basic Auth page. It worked like a charm.
URL without basic auth credentials:
URL WITH basic auth credentials:
Code used:
it('Bypass HTTP basic auth', () => {
browser.url('https://admin:admin#the-internet.herokuapp.com/basic_auth');
browser.waitForReadyState('complete');
const banner = $('div.example p').getText().trim();
expect(banner).to.equal('Congratulations! You must have the proper credentials.');
});
What I'd do is manually go through each step, trying to emulate the same flow in the script you're using. From history I can tell you, I dealt with some HTTP web-apps that required a refresh after issuing the basic auth browser.url() call.
Another way to tackle this is to make use of some custom browser profiles (Firefox | Chrome) . I know I wrote a tutorial on it somewhere on SO, but I'm too lazy to find it. I reference a similar post here.
Short story, manually complete the basic auth flow (logging in with credentials) in an incognito window (as to isolate the configurations). Open chrome://version/ in another tab of that session and store the contents of the Profile Path. That folder in going to keep all your sessions & preserve cookies and other browser data.
Lastly, in your currentCapabilities, update the browser-specific options to start the sessions with a custom profile, via the '--user-data-dir=/path/to/your/custom/profile. It should look something like this:
'goog:chromeOptions': {
args: [
'--user-data-dir=/Users/iamdanchiv/Desktop/scoped_dir18256_17319',
],
}
Good luck!

share point office 365 Get global navigation setting value in javascript file

We have developed an internal portal with multiple subsites using sharepoint office 365. We created our own page layouts/masterpage for the sites and most of the things like menu's, page body and page logos are customized(unique for all sites/subsites).
Each page has a header logo and a url assigned to that logo(logo describes site or subsite name). We have written a javascript file to load these logo and url and calling on the masterpage. Now the problem is these logo and link should load based on Global navigation
Example:
If the site is using the same navigation items as the parent site?
Yes - pull logo and link from site above
No - pull logo and link according to site name
if i get the GlobalNavigation setting value then i can do this in javscript file. Is there a way to get this GlobalNavigation setting value in javascipt file? I googled on this but didn't get enough information.
Thanks in advance,
Amarnath
--------UPDATED-------
I am using the below code but getting error "sp.runtime.js:2 Uncaught Error: The property or field 'Source' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested"
used code
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
//Navigation Provider Settings for Current Web.
var webNavSettings = new SP.Publishing.Navigation.WebNavigationSettings(ctx, web);
//Global Navigation (Top Navigation Bar)
var navigation = webNavSettings.get_globalNavigation();
navigation.set_source(1);
webNavSettings.update();
ctx.executeQueryAsync(onSuccess, onFailure);

How do I load phonegap/cordova with jade?

I am developing a Web Application using node.js, express and jade. I have the following jade template which I am seeing using a WebView in a Phonegap application:
doctype mobile
html
head
script(src="cordova-2.1.0.js")
script
var ready = function() {
alert(\'Ready\');
}
document.addEventListener("deviceready", ready);
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
h1= title
button(id='vibrateButton', onclick='navigator.notification.vibrate(2000);')Confirm
#services
- each service in services
div.service
a(href=service.link)!= service.name
div.desc= service.description
What this template will produce is a webpage with a list of items (a description and a link) which will be fetched from a mongo database. The page is served using node.js
Now, the cordova script is not loading because the alert ("Ready") is not being displayed. Also, if I hit the button the device won't vibrate and the console will display the following message:
Uncaught TypeError: Cannot call method 'vibrate' of undefined at http://xx.xxx.xx.x:3000/:5
How can I include the Phonegap script using jade? I have tried to load simple scripts with just an alert and it works, but in this case I don't know why it is not working.
Could anyone provide advise please? Thanks.
With recent changes to cordova, you should take a look into InAppBrowser api. That's the recommended way to deal with remote pages embedded in your application.
In the end, you'll probably have a single index.html on the application to make sure the cordova js api is loaded and everything is ok. Then you'll open an InAppBrowser targeting your remote page (remember to whitelist it on config.xml for a better experience!).
The dot after the script is missing. Read this:
"Often you might want large blocks of text within a tag. A good
example is with inline scripts or styles. To do this, just add a .
after the tag (with no preceding space)"
It's taken from the jade-lang reference.
Example:
script.
if (usingJade)
console.log('you are awesome')
else
console.log('use jade')
Will render:
<script>
if (usingJade)
console.log('you are awesome')
else
console.log('use jade')
</script>
these will never work.
the html pages needs to be on the client side( app side ) not in the server side(node).
Example. In a android phonegap proyect on the assets\www folder.
i dont know for wat SO is your app, but
App client side: views, phonegap, jquery .... and all the stuff to request the data to the node server.
Server side: dbStuff, and all the stuff to retrieve the data to the app requests.
hope it helps.

Opening and writing to a new window from a Google Chrome extension sandbox page

(Cross posted here)
Hi,
I have a sandboxed page (specified in my manifest) which is loaded into an iframe in my extension's background page. From within my sandboxed page, I'd like to open a new window and write to it, i.e.:
var win = window.open(); win.document.write('<p&gtHello!</p>');
This works from my extension's background page and from regular web pages, but when invoked from either content scripts or my sandboxed page, the window opens, but I cannot access the win object (it's defined, but empty---console.log outputs "Window {}").
I assume this is due to same-origin policies (with every window being given a uinque-origin within the sandboxed environment). However, since the window opens an about:blank page, I'm confused why this would matter.
Is this a feature? Is there a parameter I can add to my manifest to avoid this? And does anyone know of work-arounds that don't involve using postMessage back to my background page? My ideal solution is to have my sandboxed script open a new window and interact with it directly, not with message passing.
I can provide a full example if necessary, but I'm hoping someone might just know off the top of their head. I'm running Chrome 24.0.1312.57 on Mac and 24.0.1312.68 on Ubuntu if that helps.
Thanks,
Hank
Content scripts, by definition, are part of external regular web pages you load so I'm not really sure how your script could work on a "regular web page" but not the content script. Do you mean the code works when you embed it in your own pages, but not in other pages via the content script?
Regardless, if the script is working properly from your background page, you could always try messaging. (more here: http://developer.chrome.com/extensions/messaging.html)
Script for your sandbox/contentscript:
//send message to background page
chrome.extension.sendMessage({todo: "newWindow"});
In background page:
//create a listener
chrome.extension.onMessage.addListener(
function(request, sender) {
if (request.todo === "newWindow") {
//do your stuff here
var win = window.open(); win.document.write('<p&gtHello!</p>');
}
});
Per the cross-post here, the issue is indeed that the opened window is given a unique origin. This was intentional as the members of the standards working group (SWG) felt that it would be more secure to not make an exception for about:blank pages where they inherit the sandbox's origin.
However, to get around this issue, at least for my purposes, I can use the following method. First, forget sandboxing. This workaround uses an iframe embedded in a background page with the src url set to data:text/html,.... This gives a unique origin to the iframe so it's no longer in extension space. That means eval can be used and chrome apis cannot be accessed. Unlike in a sandbox, windows opened from the iframe share that same origin as the iframe, allowing created windows to be accessed. For example:
In a background html page:
<html>
<head>
...
<script src="background.js"></script>
...
</head>
<body>
...
<iframe id="myframe"></iframe>
...
</body>
</html>
In background.js:
...
document.getElementById('myframe').setAttribute('src', 'data:text/html,'+
encodeURI('<html><head>'+
'<script src='+chrome.extension.getURL('jquery.js')+'></script>'+
'<script src='+chrome.extension.getURL('myscript.js')+'></script>'+
...
'</head><body></body></html>'
));
...
In myscript.js
jQuery(document).ready(function(){
...
// To receive messages from background.js.
window.addEventListener('message', function(e){ ... } );
// To send messages to background.js.
parent.postMessage({...}, '*');
// To open AND ACCESS a window.
var win = window.open();
win.document.write('Hello'); // Fails in sandbox, works here.
// Eval code, if you want. Can't do this from an extension
// page loaded normally unless you allow eval in your manifest.
// Here, it's okay!
eval( 'var x = window.open(); x.document.write("Hi!")' );
// No chrome apis.
chrome.log( chrome.extension ); // -> undefined
chrome.log( chrome.windows ); // -> undefined
// No direct access to background page (e.g., parent).
chrome.log( parent ); // -> Window with no properties.
...
});

Unable to use getBackgroundPage() api from a devtools extension

I am trying to write an extension that adds functionality to the Chrome devtools.
According to the devtools documentation, it says that the pages in devtools support very limited apis. Any API that is not supported can be access by accessing it through the background page, just as what contentscripts does.
Here is the relevant documentation snippet:
The tabId property provides the tab identifier that you can use with the chrome.tabs.* API calls. However, please note that chrome.tabs.* API is not exposed to the Developer Tools extension pages due to security considerations — you will need to pass the tab ID to the background page and invoke the chrome.tabs.* API functions from there.
Here is the source url: http://developer.chrome.com/extensions/devtools.inspectedWindow.html
However, when I try to do that, I get the following error in the console:
uncaught Error: "getBackgroundPage" can only be used in extension processes. See the content scripts documentation for more details.
Here is my code in my devtools.js script:
chrome.extension.getBackgroundPage().getLocation();
What am I doing wrong?
EDIT
I should describe my scenario first, and show how I am implementing it.
What I want to do is to display extra data in a devtools panel related to a webpage. In order to get that data, I will need to send a HTTP request in the same session as the page being debugged, because it requires authentication.
Use Case:
User browses to a particular URL. He is authenticated to the site. He then invokes devtools. The devtools panel opens up and a new panel shows up that has extra data related to the page.
Implementation:
1) DevTools script finds out the url of the page being inspected. If the url matches the site base hostname, then it opens a panel. In the callback of the panel creation, it sends a message to a background page, asking it to download a JSON payload from a debug endpoint on the same site, and then sends it to the devtools extension, wh ich then displays it.
Problems:
1) The background page gets the request, and downloads the URL. However the download is not using the same session as the user, so the download request fails.
2) From devtools window, I got the tabId of the inspected window. I send this tabId to the background page so that it can parse some stuff out of the url. However, chrome.tabs.get(tabId) does not return the tab.
To summarize, I need to
1) Get the background page to download data in the same session as the user's tab that is being debugged.
2) I need to have the background page be able to get access to the user's tab.
The APIs available to extension pages within the Developer Tools window include all devtools modules listed above and chrome.extension API. Other extension APIs are not available to the Developer Tools pages, but you may invoke them by sending a request to the background page of your extension, similarly to how it's done in the content scripts.
I guess the documentation is little ambiguous, By chrome.extension API they mean the Supported API's for content scripts.
So, you can use long lived communication for communication between inspected page and background page
Demonstration:
The following code illustrate scenario where a devtools page need some information from background page, it uses messages for communication.
manifest.json
Ensured permissions are all available in manifest file
{
"name":"Inspected Windows Demo",
"description":"This demonstrates Inspected window API",
"devtools_page":"devtools.html",
"manifest_version":2,
"version":"2",
"permissions":["experimental"],
"background":{
"scripts" : ["background.js"]
}
}
devtools.html
A trivial HTML File
<html>
<head>
<script src="devtools.js"></script>
</head>
<body>
</body>
</html>
devtools.js
Used Long lived Communication API's
var port = chrome.extension.connect({
name: "Sample Communication"
});
port.postMessage("Request Tab Data");
port.onMessage.addListener(function (msg) {
console.log("Tab Data recieved is " + msg);
});
background.js
Responded to communication request and passed trivial information using tab API()'s
chrome.extension.onConnect.addListener(function (port) {
port.onMessage.addListener(function (message) {
chrome.tabs.query({
"status": "complete",
"currentWindow": true,
"active": true
}, function (tabs) {
port.postMessage(tabs[0].id);
});
console.log("Message recived is "+message);
});
});
Sample Output received for trivial devtools.js here
Let me know if you need more information
EDIT 1)
For your question 1)
Can you make you call(s) from browser extension HTML Page\Content Script so same session is shared, i have tried both the ways in a sample and it is working form me, instead of code in background page- make the code in content script or browser action HTML Page.
Let me know if you are still facing problems.
For your question 2)
The following code always fetches current window user is browsing
manifest.json
Ensure you have tabs permission in your manifest.
{
"name":"Inspected Windows Demo",
"description":"This demonstrates Inspected window API",
"manifest_version":2,
"version":"2",
"permissions":["tabs"],
"background":{
"scripts" : ["background.js"]
}
}
background.js
chrome.tabs.query({
"status": "complete", // Window load is completed
"currentWindow": true, // It is in current window
"active": true //Window user is browsing
}, function (tabs) {
for (tab in tabs) { // It returns array so used a loop to iterate over items
console.log(tabs[tab].id); // Catch tab id
}
});
Let me know if you are still unable to get tab id of current window.

Resources