IBM PCOMM Automation using Java - java

I am trying to automate IBM PComm Application using HACL Java library classes .
I have succeeded in establishing connection to the pcom session as well as set /get cursor position and extracting text from the current cursor position on the application's screen. But unable to put / send text at a desired cursor position on the screen. Kindly help in resolving this issue .Please find the code for establishing connection and fetch text from the screen as below :
import java.util.Properties;
import com.ibm.eNetwork.ECL.ECLConnMgr;
import com.ibm.eNetwork.ECL.ECLConnection;
import com.ibm.eNetwork.ECL.ECLErr;
import com.ibm.eNetwork.ECL.ECLField;
import com.ibm.eNetwork.ECL.ECLFieldList;
import com.ibm.eNetwork.ECL.ECLPS;
import com.ibm.eNetwork.ECL.ECLSession;
import org.ohio.iOhioScreen;
public class Pcom {
public static void main(String[] args) throws ECLErr {
try{
System.loadLibrary("pcseclj");
Properties prop = new Properties();
// prop.put("SESSION_VT_LOCAL_ECHO ", "true");
prop.put("SESSION_HOST", "C:\\Mainframe\\A.ws"); // works OK
prop.put("SESSION_WIN_STATE", "MAX");
prop.put("SESSION_VT_KEYPAD ", "SESSION_VT_KEYPAD_APPL");
prop.put("SESSION_VT_LOCAL_ECHO", "SESSION_VT_LOCAL_ECHO_ON");
ECLSession session = new ECLSession(prop);
session.StartCommunication(); //works OK
Thread.sleep(5000);
session.connect(); //works OK
ECLFieldList fieldList = session.GetPS().GetFieldList();
session.GetPS().SetCursorPos(18, 044); //works OK
/session.GetPS().SetString("some_text"); // does not work
for(int i=0;i<fieldList.size();i++){ //works OK
//System.out.println("field ======================= "+fieldList.GetFirstField(i).getAttribute());
ECLPS ps=session.GetPS();
System.out.println(session.GetName()); //works Ok
session.GetPS().SetCursorPos(17, 44); //works OK
session.GetPS().SendKeys("some_text",17,44); // does not work ,17,44 are co ordinate positions pn screen
System.out.println(session.GetConnType()); // works ok
ps.SendKeys("some_text"); //does not work
/* ------------ does not work-------------
fieldList.FindField(17, 44).SetText("some_text");
fieldList.FindField(17, 44).SetString("some_text");
fieldList.FindField(18, 44).setString("some_text");
*/
System.out.println(fieldList.FindField(17, 44).GetLength()); // works ok
System.out.println(fieldList.FindField(17, 28).getString()); //works ok
}
catch(Exception e)
{
System.out.println(e);
}
}
}

I had similar issue before while automating PCOMM with Cucumber to make some automated regression test framework "middleware" for green screen in BDD style.
Thing is that SetCursorPos does not send new cursor position to the Host System (we use IBM i). Telnet5250 protocol is quite complicated but in few words you have two separate buffers - one on the client system (Terminal Emulator) and second on the Host System (telnet server). Usually they are sychronized, but in some circumstances they are not which leads to undefined behavior.
Litle hack is to send up and down arrow keys like this:
SendKeys("<Up>");
SendKeys("<Down>");
This will force PComm to send new cursor position to server and sync screen buffers.

Related

Selenium moveByOffset doesn't do anything

I'm running latest selenium 2.41 with Firefox 28.0 on Linux Xubuntu 13.10
I'm trying to get FirefoxDriver to move the mouse over the page (in my test, I've used the wired webpage, that has a lot of hover-activated menus), but the moveByOffset is not doing anything noticeable to the mouse, at all:
package org.openqa.mytest;
import java.util.List;
import java.io.File;
import java.lang.*;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.*;
import org.apache.commons.io.FileUtils;
public class Example {
public static void main(String[] args) throws Exception {
// The Firefox driver supports javascript
FirefoxProfile profile = new FirefoxProfile();
profile.setEnableNativeEvents(true);
WebDriver driver = new FirefoxDriver(profile);
// Go to the Google Suggest home page
driver.get("http://www.wired.com");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// now save the screenshto to a file some place
FileUtils.copyFile(scrFile, new File("./screenshot.png"));
Actions builder = new Actions(driver);
Action moveM = builder.moveByOffset(40, 40).build();
moveM.perform();
Action click = builder.click().build();
click.perform();
//click.release();
Action moveM2 = builder.moveByOffset(50, 50).build();
moveM2.perform();
Action click2 = builder.click().build();
click2.perform();
//click2.release();
Action moveM3 = builder.moveByOffset(150, 540).build();
moveM3.perform();
for( int i=0; i < 1000; i++)
{
moveM = builder.moveByOffset(200, 200).build();
moveM.perform();
Thread.sleep(500);
moveM = builder.moveByOffset(-200, -200).build();
moveM.perform();
Thread.sleep(500);
}
//Action click3 = builder.click().build();
//click3.perform();
//click3.release();
scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// now save the screenshto to a file some place
FileUtils.copyFile(scrFile, new File("./screenshot2.png"));
driver.quit();
}
}
I'm expecting the mouse the move over the different elements and trigger all the hover actions, but nothing is happening
The method moveByOffset of class Actions is or has been broken. See Selenium WebDriver Bug 3578
(The error is described some lines more down in this bug document).
A project member (barancev) claims that this error should have been fixed with Selenium version 2.42.
Nevertheless I found the same error in version 2.44 running on openSUSE 12.3 with Firefox 33.0. moveToElement works, moveToOffset doesn't.
I struggled as well getting drag and drop working.
It seems as if selenium has problems if the dragtarget is not visible, thus scrolling is requiered.
Anyway, that's the (Java) code that works. Note that I call "release()" without an argument - neither the dropable Element nor the dragable Element as argument worked for me. As well as "moveToElement(dropable)" didnt work for me, that's why I calculated the offset manually.
public void dragAndDrop(WebElement dragable, WebElement dropable,
int dropableOffsetX, int dropableOffsetY) {
Actions builder = new Actions(driver);
int offsetX = dropable.getLocation().x + dropableOffsetX
- dragable.getLocation().x;
int offsetY = dropable.getLocation().y + dropableOffsetY
- dragable.getLocation().y;
builder.clickAndHold(dragable).moveByOffset(offsetX, offsetY).release()
.perform();
}
i was also struggling with this and the solution that worked for me is below we have to add 1 to either X or Y co-ordinate.
Looks like (x,y) takes us to the edge of the element where its not clickable
Below worked for me
WebElement elm = drv.findElement(By.name(str));
Point pt = elm.getLocation();
int NumberX=pt.getX();
int NumberY=pt.getY();
Actions act= new Actions(drv);
act.moveByOffset(NumberX+1, NumberY).click().build().perform();
you could even try adding +1 to y coordinate that also works
act.moveByOffset(NumberX+1, NumberY).click().build().perform();
Please try using moveToElement. It should work.
Actions action = new Actions(webdriver);
WebElement we = webdriver.findElement(By.xpath("<XPATH HERE>"));
action.moveToElement(we).moveToElement(webdriver.findElement(By.xpath("/expression-here"))).click().build().perform();
i suggest that if your browser is not perform movetoelement and move to offset then you have put wrong offset of element
for find offset you use Cordinates plugin in chrome

Read data from GUI

I have a general question :
If I got a GUI (e.g. metaTrader => online broker), is it possible to read data from this GUI using java?
My idea:
Using the java.awt.robot and do something like:
package java_robot;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
public class java_robot {
public static void main(String[] args) {
try {
// create class
Robot robot = new Robot();
// wait 1 sec
robot.delay(1000);
// move mouse to wanted area
robot.mouseMove(x, y);
}
// mark an area, copy it and save in file..
} catch (AWTException e) {
e.printStackTrace();
}
}
}
Is this idea good, or do you know other solutionĀ“s to read data from a GUI?
(working on mac)
You can use the Robot#createScreenCapture() method here.
Robot r = new Robot();
// Capture area
int width = ...
int height = ...
Rectangle area = new Rectangle(width, height);
BufferedImage image = r.createScreenCapture(area);
// Save to file
ImageIO.write(image, "png", new File("/screenshot.png"));
Alternatively, if metaTrader loads its data from internet, you can sniffe its traffic and determine how and where its data comes. Then you could try to mimic its internet calls and get the data yourself as long as it is not ciphered.
You could also build a proxy in Java and ask metaTrader to use this proxy. All data requested by metaTrader would go through your proxy. This can give you a chance to read the data... again as long as it is not ciphered.
The image below illustrates how things work. Alice plays the role of meaTrader. Bob is the source of data of metaTrader. Proxy is your Java app.
You can find a simple implementation of such a proxy here: http://www.java2s.com/Code/Java/Network-Protocol/Asimpleproxyserver.htm.
References:
Proxy server

How to create an E-Mail in Outlook and make it visible for the User

I want to create an E-Mail with a Java Application using Outlook and the OLE Client.
I searched for examples and found quite a few. They all start the same way:
Create the Display, the Shell, the OLE Frame and the OLE Client Site.
But I get an error with these few steps:
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Outlook Automation");
shell.setLayout(new FillLayout());
OleFrame frm = new OleFrame(shell, SWT.NONE);
OleClientSite site = new OleClientSite(frm, SWT.NONE,
"Outlook.Application");
I get the following Error:
Exception in thread "main" org.eclipse.swt.SWTException: Failed to create Ole Client. result = -2147221164
at org.eclipse.swt.ole.win32.OLE.error(OLE.java:302)
at org.eclipse.swt.ole.win32.OleClientSite.<init>(OleClientSite.java:242)
at outlooktest.Main.main(Main.java:27)
I don't know OLE and I'm not sure what I am doing wrong. Are there some dependencies I'm missing? Does somebody know what this error could be? I googled for the Error code but didn't find anything.
EDIT
Well if nobody knows why OLE doesn't work for me I've got another question. Is it possible, or is there a Library, to create an Outlook E-Mail and set it up (subject, body etc) but not send it but make it visible for the User to change things?
EDIT 2
The x86 and x64 jar files didn't work out, same error. Also I got the newest versions of SWT for x86 and x64. OS is x64 and java, too, so I can't use the x86 SWT libraries. With the x64 the error above occurs. The Outlook version is 15 (Outlook 2013).
Hopefully this helps?
I got the creation of E-Mail to work via Processbuilder but only with the mailto: parameter. The problem here is the folllowing:
I want to track the status of the Process. I want to know when the E-Mail is closed/send whatsoever.
I want to insert a picture (BufferedImage) out of the Clipboard into the Body, which is simply impossible with the mailto argument.
For me this works nicely according to a tutorial on vogella.com. I also tried your minimal code sample and got no error during OLE client creation. I used SWT 4.3, by the way.
A little off-topic, but does it have to be Outlook? I mean, do you just want to automate e-mail sending - you could use JavaMail and do it headlessly, i.e. without automating an actual GUI client. The only reasons I can imagine for wishing to use Outlook or another e-mail client are:
You need the sent message in your out-box for reference.
Outlook is connected to an Exchange server which is configured to not accept SMTP connections as used by JavaMail.
You might want to compose a basic message and show it to the user so she can add attachments or edit the text interactively before sending.
But if it is just about automating e-mail sending, as I said I would recommend JavaMail.
Update: I downloaded SWT from its home page, in my case the latest stable release 4.3 for Windows. In the ZIP archive the file you need is swt.jar.
My sample code looks like this and is working fine:
package de.scrum_master.ole;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class OutlookMail {
public static void main(String[] args) {
sendEMail();
}
public static void sendEMail() {
Display display = new Display();
Shell shell = new Shell(display);
OleFrame frame = new OleFrame(shell, SWT.NONE);
// This should start outlook if it is not running yet
// OleClientSite site = new OleClientSite(frame, SWT.NONE, "OVCtl.OVCtl");
// site.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
// Now get the outlook application
OleClientSite site2 = new OleClientSite(frame, SWT.NONE, "Outlook.Application");
OleAutomation outlook = new OleAutomation(site2);
OleAutomation mail = invoke(outlook, "CreateItem", 0 /* Mail item */).getAutomation();
setProperty(mail, "BodyFormat", 2 /* HTML */);
setProperty(mail, "Subject", "My test subject");
// setProperty(mail, "From", "my#sender.org");
setProperty(mail, "To", "<John Doe> my#recipient.org");
setProperty(mail, "HtmlBody", "<html><body>This is an <b>HTML</b> test body.</body></html>");
// if (null != attachmentPaths) {
// for (String attachmentPath : attachmentPaths) {
// File file = new File(attachmentPath);
// if (file.exists()) {
// OleAutomation attachments = getProperty(mail, "Attachments");
// invoke(attachments, "Add", attachmentPath);
// }
// }
// }
invoke(mail, "Display" /* or "Send" */);
}
private static OleAutomation getProperty(OleAutomation auto, String name) {
Variant varResult = auto.getProperty(property(auto, name));
if (varResult != null && varResult.getType() != OLE.VT_EMPTY) {
OleAutomation result = varResult.getAutomation();
varResult.dispose();
return result;
}
return null;
}
private static Variant invoke(OleAutomation auto, String command,
String value) {
return auto.invoke(property(auto, command),
new Variant[] { new Variant(value) });
}
private static Variant invoke(OleAutomation auto, String command) {
return auto.invoke(property(auto, command));
}
private static Variant invoke(OleAutomation auto, String command, int value) {
return auto.invoke(property(auto, command),
new Variant[] { new Variant(value) });
}
private static boolean setProperty(OleAutomation auto, String name,
String value) {
return auto.setProperty(property(auto, name), new Variant(value));
}
private static boolean setProperty(OleAutomation auto, String name,
int value) {
return auto.setProperty(property(auto, name), new Variant(value));
}
private static int property(OleAutomation auto, String name) {
return auto.getIDsOfNames(new String[] { name })[0];
}
}
I commented out the attachments part at the end and also the first OLE command because for me it also works without it. It does not do any damage to use it though, maybe you need it. Just give it a try.
The reason why I commented out the header "From" line is that it has no effect. For changing the sender you probably need another code snippet to switch either the Outlook profile or within a profile switch several preconfigured senders. By default it will just use your default profile.
Tell me if it helps.
if you are using something with web, this can help you:
<!DOCTYPE html>
<html>
<body>
<p>
This is an email link:
<a href="mailto:someone#example.com?Subject=Hello%20again&body=your%20textBody%20here" target="_top">
Send Mail</a>
</p>
<p>
<b>Note:</b> Spaces between words should be replaced by %20 to ensure that the browser will display the text properly.
</p>
</body>
</html>
but in a application you can start a process mailto:
like
System.Diagnostics.Process.Start("mailto:someone#example.com?Subject=Hello%20again&body=your%20textBody%20here")
it will work with all e-mail clients
com,
System.Diagnostics.Process.Start("mailto:someone#example.com?Subject=Hello%20again&body=your%20textBody%20here")
with the above code Outlook mail is opened with predefined mailto, Subject and Body of the mail, could you please explain me how can we Add the address in CC also.
Your MS Outlook might be 32-bit (x86). So a 64-bit (x64) SWT cannot start the outlook. You need to use 32-bit SWT Jar File which will not run on 64-bit JVM. So you need to install 32-Bit JVM (JRE).
Even if you are running 64-bit Windows, you can still download and install the 32-bit (x86) JRE and run your application.

Grab a screenshot of Chrome using Chrome Developer Tools?

Is it possible to grab a screenshot of an open window using the Chrome Development Tools remote debugger?
For example, I'm connecting to the remote debug port and I have this
code which pops an empty window:
private void sendWindowPop(int width, int height) throws
IOException {
hsc.send("{\"method\": \"Runtime.evaluate\", \"id\": "
+ hsc.nextInt()
+ ", \"params\": {"
+ "\"expression\":
\"window.open('about:blank','name','toolbar=0,scrollbars=0,"
+ "location=0,status=0,menubar=0,resizable=0,width="
+ width
+ ",height="
+ height
+ "');\""
+ "}}");
(hsc is my connection to the debugger at http://localhost:9222)
Then, I load up my target URL with this:
private void loadPage(String uriString) throws IOException {
hsc.send("{\"method\": \"Page.open\", \"id\": " +
hsc.nextInt() + ", \"params\": {\"url\": \"" + uriString + "\"}}");
hsc.waitFor(ChromeNotifications.PAGE_LOADEVENTFIRED, DEFAULT_TIMEOUT_MILLIS);
}
The code above works fine, and first pops a window and then loads the
URL. Ideally, the next thing I would like to do is grab a screenshot
of the loaded web page. Right now, these browser windows pop into an
Xvfb virtual desktop, and I can use ImageMagick's import tool to grab
a screenshot of the target window, but only if it's in the
foreground.
This is a problem, since this application is designed to run in
parallel with multiple windows popping into the virtual desktop. Any
window overlapping my target window will just give me a black
screenshot, since Xfvb only renders what's visible.
I also looked into the API reference, chrome.tabs.captureVisibleTab. No luck there, it doesn't capture what's not visible.
Is there a way, using the remote debugger, to grab a screenshot of an
open window?
(for reference purposes, my ImageMagick command for import is this)
DISPLAY=:0.0 import -window "Google - Chromium" screenshot.png
Where I open the URL http://www.google.com in my chromium browser using loadPage() above. It works great as long as the "Google - Chromium" window that pops is unobstructed and has focus. Drop another window over part of it, and I get a big black area that was not rendered.
Thanks!
Chrome Remote Debugging Protocol now supports the Page.captureScreenshot function
Here is an example in coffee-script
screenshot: (name, callback)=>
safeName = name.replace(/[^()^a-z0-9._-]/gi, '_') + ".png"
png_File = "./_screenshots".append_To_Process_Cwd_Path().folder_Create()
.path_Combine(safeName)
#chrome._chrome.Page.captureScreenshot (err, image)->
require('fs').writeFile png_File, image.data, 'base64',(err)->
callback()
(snippet from
https://github.com/TeamMentor/TM_4_0_Design/blob/Issue_80_Jade_Cleanup/QA/API/QA-TM_4_0_Design.coffee#L54)
Try the Aviary Screen Capture
Check this site too:
http://www.webdesignerdepot.com/2011/08/25-must-have-chrome-extensions-for-web-designers-and-developers/
If you need Java based solution use cdp4j to capture full page screen.
public static void main(String[] args) throws IOException, InterruptedException {
SessionFactory factory = new Launcher().launch();
Path file = createTempFile("screenshot", ".png");
try (Session session = factory.create()) {
session.navigate("https://webfolder.io");
session.waitDocumentReady();
byte[] data = session.captureScreenshot();
write(file, data);
}
if (isDesktopSupported()) {
getDesktop().open(file.toFile());
}
factory.close();
}
Screenshot.java

Can Verification Java API in Digital Persona One Touch run w/o RTE?

Does this code require the Digital Persona One Touch RTE (Runtime environment) to work?:
DPFPVerification verifier = DPFPGlobal.getVerificationFactory().createVerification();
If so, is there another way to verify Digital Persona SampleFeatures (serialized) against a Digital Persona Template (serialized) using only the dpfp JARs?
Reason: We plan to have our DPFP verifier on a Web Service provided by TIBCO.
Any help is greatly appreciated!
I get a Java JNI exception with this sample test main code:
import com.digitalpersona.onetouch.DPFPFeatureSet;
import com.digitalpersona.onetouch.DPFPFeatureSetFactory;
import com.digitalpersona.onetouch.DPFPGlobal;
import com.digitalpersona.onetouch.DPFPTemplate;
import com.digitalpersona.onetouch.DPFPTemplateFactory;
import com.digitalpersona.onetouch.verification.DPFPVerification;
import com.digitalpersona.onetouch.verification.DPFPVerificationResult;
public class Main {
/**
* fingerScanTemplate is from WC DB
* sample is from the WS input parameters
*/
public boolean performVerification(byte[] fingerScanTemplate, byte[] sampleFeatures) {
DPFPTemplateFactory templateFactory = DPFPGlobal.getTemplateFactory();
DPFPFeatureSetFactory featureSetFactory = DPFPGlobal.getFeatureSetFactory();
DPFPVerification verifier = DPFPGlobal.getVerificationFactory().createVerification();
// Deserialize template & sampleFeature
DPFPTemplate deserializedTemplate = templateFactory.createTemplate(fingerScanTemplate);
DPFPFeatureSet features = featureSetFactory.createFeatureSet(sampleFeatures);
//Compare the feature set with the template, based on which finger was captured
DPFPVerificationResult result = null;
result = verifier.verify(features, deserializedTemplate);
return result != null && result.isVerified();
}
/**
* #param args
*/
public static void main(String[] args) {
new Main().performVerification(null, null);
}
}
No you should not need some sort of RTE. I do know that I had to have the One Touch SDK installed because it runs a windows service called Biometric scanning or something similar. The main problem I see with your code is that:
DPFPVerificationResult result = null;
result = verifier.verify(features, deserializedTemplate);
Needs to be:
DPFP.Verification.Verification.Result result = new DPFP.Verification.Verification.Result();
verifier.verify(features, template, ref result );
At least that is what got my code to start verifying correctly. I also had to fix a programmer's mistake in creating the FeatureSet which needs to be done like this:
DPFP.FeatureSet features = ExtractFeatures(Sample, DPFP.Processing.DataPurpose.Verification);
I have a feeling you are using an older SDK than I am but maybe this will help out some.

Categories

Resources