Because it was a quite frustrating experience I wanted to share my insights on this blog
Step 1 : Configure File Locations in Cognos
I followed this manual in configuring archive locations http://queryvision.com/reportstofilesystem_individual/
The folders get published as a saving to location in the advanced options when running a report.
It's import that the User account which is running the Cognos express Service has write acces to the given file location
Step 2 : Running the report from a URL
After serveral hours reading documentation I learned that the cognos API allows to open a report and even supports sending parameters with it. I found a good reference for this here
http://public.dhe.ibm.com/software/dw/dm/cognos/reporting/scripting_techniques/using_urls_in_cognos_8.pdf
Example URL was
http://192.168.1.105:19300/p2pd/servlet/dispatch?ui.name=TestingTheAPI&run.outputFormat=PDF&run.prompt=false&p_myparameterfield=XXXX&ui.action=run&b_action=cognosViewer&encoding=UTF-8&ui.object=myreportlocation&ui=m1m2m3m4&ui.backURL=http%3a%2f%2f192.168.1.105
In the API I however did NOT find anyway to specify the archive location. When running the report manually you must shedule the report (now) to be able to choose a archive location. I think this explains why just calling a specific URL doesn't allow to shedule it.
Step 3: Finding a way to script it
My 3e attempt was the best one, scroll further to see itAttempt 1: Refactor the HTTP requests with Wireshark ?
At first I examined the HTTP traffic with Wireshark when running the report Manually. I tried to simulate the requests but found out (the hard way) that it cannot be done this way. On each page Cognos runs some Javascript function that sets SESSION information. Refactoring the request I stumbled a lot on tracking and signature erros (which can be monitored in the 'Cognos Express\logs\cogserver.log' file)
Attempt 2: Script running the report with InternetExplorer.Application
I created a VBscript that logged in, got the report and clicked thru the site. When running the vbscript on the command shell "cscript filename.vbs" I saw the Internet Explorer window doing everything I needed
I had to tackle some issues:
The InternetExplorer object gets to '_blank' page when loading or opening a page. I wrote an "AttachObject" function for this so you can click further after each action
Sleeping some time between is always necessary and printing the current location of the Ie object is usefull 'msgbox(ie.LocationURL & "-" & ie.LocationName)
Clicking on specific object was also difficult and I wrote a "ClickOn" function to loop through the items of the current page.
Call logoff Call logon Call test Sub test() Set ie = CreateObject("InternetExplorer.Application") ie.Visible = True ie.navigate("http://192.168.1.105:19300/p2pd/servlet/dispatch?b_action=xts.run&m=portal/cc.xts&m_folder=i7747335B10784A14B04CD6DC5A9DF6E9") Do While ie.Busy Or ie.readyState <> 4 WScript.Sleep 50 Loop Found = ClickOn(ie,"Name of wanted reportname",8,False,"a") Do While ie.Busy Or ie.readyState <> 4 WScript.Sleep 50 Loop WScript.Sleep 2000 Set ie = AttachObject Found = ClickOn(ie,"Uitvoeren met opties...",0,False,"a") WScript.Sleep 2000 Set ie = AttachObject Found = ClickOn(ie,"geavanceerde opties",0,False,"a") WScript.Sleep 2000 Set ie = AttachObject ie.Document.getElementsByName("runType")(1).Click ' = True ie.Document.getElementsByName("m_ro_saveOutput")(0).Click ie.Document.getElementsByName("m_ro_archive")(0).Click Found = ClickOn(ie,"Opties bewerken...",1,False,"a") WScript.Sleep 1000 Set ie = AttachObject ie.document.getElementsByName("m_arc_filenameStub")(0).Click ie.document.getElementsByName("m_arc_filenameStub")(0).Value = "myfilenameformat" Found = ClickOn(ie,"OK",0,False,"a") WScript.Sleep 1000 Set ie = AttachObject Found = ClickOn(ie,"Uitvoeren",0,False,"a") 'Promptscreen WScript.Sleep 1000 Set ie = AttachObject Found = ClickOn(ie,"SpecificRadioOptionValue",0,False,"input") 'radio button 'Select on class ie.document.getElementsByClassName("clsTextWidget")(1).value = "param1" ie.document.getElementsByClassName("clsTextWidget")(2).value = "param2" Found = ClickOn(ie,"Finish",0,False,"button") 'Finish Do While ie.Busy Or ie.readyState <> 4 WScript.Sleep 50 Loop msgbox("END = " & ie.LocationURL & "-" & ie.LocationName ) ie.Quit End Sub Sub logon() Set ie = CreateObject("InternetExplorer.Application") ie.Visible = True ie.Navigate "http://192.168.1.105:19300/p2pd/servlet/dispatch?b_action=xts.run&m=portal/cc.xts&gohome=" Do While ie.Busy Or ie.readyState <> 4 WScript.Sleep 50 Loop ie.Document.getElementsByClassName("loginButton")(0).click Do While ie.Busy Or ie.readyState <> 4 WScript.Sleep 50 Loop ie.Document.getElementsByName("CAMUsername")(0).value = "myusername" ie.Document.getElementsByName("CAMPassword")(0).value = "mypassword" ie.Document.getElementsByClassName("loginButton")(0).click Do While ie.Busy Or ie.readyState <> 4 WScript.Sleep 50 Loop 'msgbox(ie.LocationURL & "-" & ie.LocationName) ie.Quit End Sub Sub logoff() Set ie_logoff = CreateObject("InternetExplorer.Application") ie_logoff.Visible = True ie_logoff.Navigate "http://192.168.1.105:19300/p2pd/servlet/dispatch?b_action=xts.run&m=portal/logoff.xts&h_CAM_action=logoff" Do While ie_logoff.Busy Or ie_logoff.readyState <> 4 WScript.Sleep 50 Loop 'msgbox(ie.LocationURL & "-" & ie.LocationName) ie_logoff.Quit End Sub Function AttachObject strPath = "http://192.168.1.105:19300/p2pd/servlet/dispatch" Set oShell = CreateObject("WScript.Shell") Set objShellWindows = CreateObject("Shell.Application").Windows For X = objShellWindows.Count - 1 To 0 Step -1 Set oIE = objShellWindows.Item(X) If Not oIE Is Nothing Then ' Uncomment below line to troubleshoot ' MsgBox oIE.LocationName & vbCrLf & oIE.LocationURL 'If StrComp(oIE.LocationURL, "file:///" & Replace(strPath, Chr(92), "/", 1, -1, 1), 1) = 0 Then If StrComp(oIE.LocationURL, strPath, 1) = 0 Then Do While oIE.Busy And oIE.ReadyState < 2 DoEvents Loop oIE.Visible = 2 Exit For End If End If Set oIE = Nothing Next Set objShellWindows = Nothing If oIE Is Nothing Then MsgBox "Could Not Find The IE Window" Set AttachObject = null else Set AttachObject = oIE 'msgbox("status = " & oIE.LocationURL & "-" & oIE.LocationName ) End If End Function Function ClickOn(oIE,SearchString,index,debugging,tag)'Index = number of items after found item which will be clicked'msgbox("status = " & ie.LocationURL & "-" & ie.LocationName ) set urls = oIE.document.all.tags(tag) For x = 0 to (urls.length)-1 if tag = "a" or tag = "button" then If Debugging then msgbox x & "=" & urls(x).innerHTML & " : " & urls(x).href End if If Instr(urls(x).innerHTML,SearchString) > 0 Then If Debugging then msgbox "Found " & x & "=" & urls(x).innerHTML End if urls(x+index).Click ClickOn = True Exit For else 'msgbox x & "van " & urls.length-1 & " " & Trim(urls(x).innerHTML) & " : " & urls(x).href End if Else 'for now only "input" items If Debugging then msgbox x & "=" & urls(x).Value End if if Instr(urls(x).value,SearchString) > 0 Then If Debugging then msgbox "Found " & x & "=" & urls(x).innerHTML End if urls(x+index).Click ClickOn = True Exit For End if End if Next End Function
As you can see working with the IE object had some downfalls. I had to reattach the object , wait unspecific amount of time to proceed the next step etc, but it actually worked. After installing it on the server in stead of my local machine I learned that the older IE version on the server did not supported some features. This made me pursue other ways of scripting the report.
Attempt 3: PhantomJS to the rescue
PhantomJS is described as a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
After some testing I decided to transform my old script to a PhantomJS script which workes a lot better
- the CSS selector makes it much easier to select a element to click on for example
- the render function allows to make printscreens of the active screen in every step
- it's possible to run a Javascript function on the page itself
- PhantomJS can run on any windows machine (independant of the installed IE version)
The script needs to be called with a parameter for example
phantomjs.exe myscriptname.js parameter1
var page = new WebPage(), testindex = 0, loadInProgress = false;
uid = "myusername";
pwd = "mypassword";
DocumentName = "My documentname";
FolderID = "i535F689A7E43421B995CC9B577DA499A"
Archive_location = "Facturen Vorming"
var system = require('system');
if (system.args.length === 1) {
console.log('Try to pass some args when invoking this script!');
} else {
system.args.forEach(function (arg, i) {
console.log(i + ': ' + arg);
if(i == 1) { Parameter1 = arg;}
});
}
console.log("==========================");
console.log("Parameter1 = " + Parameter1);
console.log("==========================");
//var parameter1 = phantom.args[0];
page.onConsoleMessage = function(msg) { console.log(msg);};
page.onLoadStarted = function() { loadInProgress = true; console.log(" Laden...");};
page.onLoadFinished = function() { loadInProgress = false; console.log(" OK");};
var steps = [
function() {
//Load Login Page
console.log("Stap 1 Login pagina");
console.log("============================================");
page.open("http://192.168.1.105:19300/p2pd/servlet/dispatch?b_action=xts.run&m=portal/cc.xts&gohome=");
},
function() {
console.log("Stap 2 Choose Authentication");
console.log("============================================");
page.evaluate(function() {
var Knop = document.getElementsByClassName("loginButton");
Knop[0].click();
});
},
function() {
console.log("Stap 3 Enter Credentials :" + uid);
console.log("============================================");
page.evaluate(function(uid,pwd) {
document.querySelector("input[name='CAMUsername']").value = uid;
document.querySelector("input[name='CAMPassword']").value = pwd;
document.querySelector("#LoginForm").submit();
},uid,pwd);
},
function() { console.log("Stap 4 Printscreen"); page.render('4_Printscreen.png'); },
function() {
console.log("Stap 5 Open bewuste map");
console.log("============================================");
page.open("http://192.168.1.105:19300/p2pd/servlet/dispatch?b_action=xts.run&m=portal/cc.xts&m_folder=" + FolderID)
},
function() {
console.log("Stap 6 Klik op Uitvoeren met opties ");
console.log("============================================");
page.evaluate(function(DocumentName) {
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("img[title='Uitvoeren met opties - " + DocumentName + "']").dispatchEvent( event );
},DocumentName);
},
function() { console.log("Stap 7 Printscreen"); page.render('7_Printscreen.png'); },
function() {
console.log("Stap 8 Klik op Geavanceerde opties");
console.log("============================================");
page.evaluate(function() {
/*var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("a[href='javascript:advancedOptions()']").dispatchEvent( event );*/
advancedOptions();
});
},
function() { console.log("Stap 9 Printscreen"); page.render('9_Printscreen.png'); },
function() {
console.log("Stap 10 Opties kiezen");
console.log("============================================");
page.evaluate(function() {
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("input[type='radio'][name='runType'][value='background']").dispatchEvent( event );
var event2 = document.createEvent( 'MouseEvents' );
event2.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("input[type='checkbox'][name='m_ro_saveOutput']").dispatchEvent( event2 );
var event3 = document.createEvent( 'MouseEvents' );
event3.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("input[type='checkbox'][name='m_ro_archive']").dispatchEvent( event3 );
var event4 = document.createEvent( 'MouseEvents' );
event4.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("a[href='javascript:utmlA_d0n47095()']").dispatchEvent( event4 );
});
},
function() { console.log("Stap 11 Printscreen"); page.render('11_Printscreen.png'); },
function() {
console.log("Stap 12 Enter Filename");
console.log("============================================");
page.evaluate(function(Parameter1,Archive_location) {
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("input[type='radio'][value='specify_name']").dispatchEvent( event );
//Gewenste Filename
document.querySelector("input[name='m_arc_filenameStub']").value = "nameconvention-"+Parameter1;
// Kies locatie
document.querySelector('option[selected]').value = "/configuration/archiveLocation[@name='"+Archive_location+"']";
// Behoud bestaande bestanden
var event3 = document.createEvent( 'MouseEvents' );
event3.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("input[type='radio'][name='m_arc_conflictResolution']").dispatchEvent( event3 );
var event4 = document.createEvent( 'MouseEvents' );
event4.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
//page.render('14_Printscreen.png');
var links = document.getElementsByTagName('a');
//for(var l in links) {
for (var i = 0; i < links.length; i++) {
if (links[i].innerHTML.indexOf('OK') !== -1) {
console.log("--found OK button");
links[i].dispatchEvent(event4) ;
}
}
},Parameter1,Archive_location);
},
function() { console.log("Stap 13 Printscreen"); page.render('13_Printscreen.png'); },
function() {
console.log("Stap 14 Run");
console.log("============================================");
page.evaluate(function() {
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("a[aria-label='Uitvoeren']").dispatchEvent( event );
});
},
function() { console.log("Stap 15 Printscreen"); page.render('15_Printscreen.png'); },
function() {
console.log("Stap 16 Parameters");
console.log("============================================");
page.evaluate(function(Parameter1) {
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
document.querySelector("input[type='radio'][value='Nee']").dispatchEvent( event );
document.querySelector("input[type='hidden'][name='p_Myparameter']").value = Parameter1;
oCV.promptAction('finish');
var event2 = document.createEvent( 'MouseEvents' );
event2.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
var links = document.getElementsByTagName('button');
for (var i = 0; i < links.length; i++) {
if (links[i].innerHTML.indexOf('Finish') !== -1) {
console.log("--found");
links[i].dispatchEvent(event2) ;
}
}
//document.oCV.promptAction('finish');
},Parameter1);
},
function() { console.log("Stap 17 Printscreen"); page.render('17_Printscreen.png'); },
function() {
page.evaluate(function() {
runReport();
});
},
function() {
// Output content as image
page.render('99_Printscreen.png');
}
];
interval = setInterval(function() {
if (!loadInProgress && typeof steps[testindex] == "function") {
console.log("step " + (testindex + 1));
steps[testindex]();
//console.log("uid= " + uid);
testindex++;
}
if (typeof steps[testindex] != "function") {
console.log("test complete!");
phantom.exit();
}
}, 50);
Geen opmerkingen:
Een reactie posten