Is it possible to take a screenshot using Selenium WebDriver?
(Note: Not Selenium Remote Control)
Java
Yes, it is possible. The following example is in Java:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
Python
Each WebDriver has a .save_screenshot(filename) method. So for Firefox, it can be used like this:
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://www.google.com/')
browser.save_screenshot('screenie.png')
Confusingly, a .get_screenshot_as_file(filename) method also exists that does the same thing.
There are also methods for: .get_screenshot_as_base64() (for embedding in HTML) and .get_screenshot_as_png()(for retrieving binary data).
And note that WebElements have a .screenshot() method that works similarly, but only captures the selected element.
C#
public void TakeScreenshot()
{
try
{
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ss.SaveAsFile(#"D:\Screenshots\SeleniumTestingScreenshot.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
JavaScript (Selenium-Webdriver)
driver.takeScreenshot().then(function(data){
var base64Data = data.replace(/^data:image\/png;base64,/,"")
fs.writeFile("out.png", base64Data, 'base64', function(err) {
if(err) console.log(err);
});
});
Ruby
require 'rubygems'
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :ie
driver.get "https://www.google.com"
driver.save_screenshot("./screen.png")
More file types and options are available and you can see them in file takes_screenshot.rb.
Java
I got this issue resolved. You can augment the RemoteWebDriver to give it all of the interfaces its proxied driver implements:
WebDriver augmentedDriver = new Augmenter().augment(driver);
((TakesScreenshot)augmentedDriver).getScreenshotAs(...); // It works this way
PHP (PHPUnit)
It uses PHPUnit_Selenium extension version 1.2.7:
class MyTestClass extends PHPUnit_Extensions_Selenium2TestCase {
...
public function screenshot($filepath) {
$filedata = $this->currentScreenshot();
file_put_contents($filepath, $filedata);
}
public function testSomething() {
$this->screenshot('/path/to/screenshot.png');
}
...
}
C#
public Bitmap TakeScreenshot(By by) {
// 1. Make screenshot of all screen
var screenshotDriver = _selenium as ITakesScreenshot;
Screenshot screenshot = screenshotDriver.GetScreenshot();
var bmpScreen = new Bitmap(new MemoryStream(screenshot.AsByteArray));
// 2. Get screenshot of specific element
IWebElement element = FindElement(by);
var cropArea = new Rectangle(element.Location, element.Size);
return bmpScreen.Clone(cropArea, bmpScreen.PixelFormat);
}
Java
public String captureScreen() {
String path;
try {
WebDriver augmentedDriver = new Augmenter().augment(driver);
File source = ((TakesScreenshot)augmentedDriver).getScreenshotAs(OutputType.FILE);
path = "./target/screenshots/" + source.getName();
FileUtils.copyFile(source, new File(path));
}
catch(IOException e) {
path = "Failed to capture screenshot: " + e.getMessage();
}
return path;
}
Jython
import org.openqa.selenium.OutputType as OutputType
import org.apache.commons.io.FileUtils as FileUtils
import java.io.File as File
import org.openqa.selenium.firefox.FirefoxDriver as FirefoxDriver
self.driver = FirefoxDriver()
tempfile = self.driver.getScreenshotAs(OutputType.FILE)
FileUtils.copyFile(tempfile, File("C:\\screenshot.png"))
Java (Robot Framework)
I used this method for taking a screenshot.
void takeScreenShotMethod(){
try{
Thread.sleep(10000)
BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
ImageIO.write(image, "jpg", new File("./target/surefire-reports/screenshot.jpg"));
}
catch(Exception e){
e.printStackTrace();
}
}
You may use this method wherever required.
Java
Seems to be missing here - taking screenshot of a specific element in Java:
public void takeScreenshotElement(WebElement element) throws IOException {
WrapsDriver wrapsDriver = (WrapsDriver) element;
File screenshot = ((TakesScreenshot) wrapsDriver.getWrappedDriver()).getScreenshotAs(OutputType.FILE);
Rectangle rectangle = new Rectangle(element.getSize().width, element.getSize().height);
Point location = element.getLocation();
BufferedImage bufferedImage = ImageIO.read(screenshot);
BufferedImage destImage = bufferedImage.getSubimage(location.x, location.y, rectangle.width, rectangle.height);
ImageIO.write(destImage, "png", screenshot);
File file = new File("//path//to");
FileUtils.copyFile(screenshot, file);
}
C#
using System;
using OpenQA.Selenium.PhantomJS;
using System.Drawing.Imaging;
namespace example.com
{
class Program
{
public static PhantomJSDriver driver;
public static void Main(string[] args)
{
driver = new PhantomJSDriver();
driver.Manage().Window.Size = new System.Drawing.Size(1280, 1024);
driver.Navigate().GoToUrl("http://www.example.com/");
driver.GetScreenshot().SaveAsFile("screenshot.png", ImageFormat.Png);
driver.Quit();
}
}
}
It requires NuGet packages:
PhantomJS 2.0.0
Selenium.Support 2.48.2
Selenium.WebDriver 2.48.2
It was Tested with .NET Framework v4.5.2.
PowerShell
Set-Location PATH:\to\selenium
Add-Type -Path "Selenium.WebDriverBackedSelenium.dll"
Add-Type -Path "ThoughtWorks.Selenium.Core.dll"
Add-Type -Path "WebDriver.dll"
Add-Type -Path "WebDriver.Support.dll"
$driver = New-Object OpenQA.Selenium.PhantomJS.PhantomJSDriver
$driver.Navigate().GoToUrl("https://www.google.co.uk/")
# Take a screenshot and save it to filename
$filename = Join-Path (Get-Location).Path "01_GoogleLandingPage.png"
$screenshot = $driver.GetScreenshot()
$screenshot.SaveAsFile($filename, [System.Drawing.Imaging.ImageFormat]::Png)
Other drivers...
$driver = New-Object OpenQA.Selenium.Chrome.ChromeDriver
$driver = New-Object OpenQA.Selenium.Firefox.FirefoxDriver
$driver = New-Object OpenQA.Selenium.IE.InternetExplorerDriver
$driver = New-Object OpenQA.Selenium.Opera.OperaDriver
C#
public static void TakeScreenshot(IWebDriver driver, String filename)
{
// Take a screenshot and save it to filename
Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(filename, ImageFormat.Png);
}
Java
I could not get the accepted answer to work, but as per the current WebDriver documentation, the following worked fine for me with Java 7 on OS X v10.9 (Mavericks):
import java.io.File;
import java.net.URL;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
public class Testing {
public void myTest() throws Exception {
WebDriver driver = new RemoteWebDriver(
new URL("http://localhost:4444/wd/hub"),
DesiredCapabilities.firefox());
driver.get("http://www.google.com");
// RemoteWebDriver does not implement the TakesScreenshot class
// if the driver does have the Capabilities to take a screenshot
// then Augmenter will add the TakesScreenshot methods to the instance
WebDriver augmentedDriver = new Augmenter().augment(driver);
File screenshot = ((TakesScreenshot)augmentedDriver).
getScreenshotAs(OutputType.FILE);
}
}
There are multiple methods through Selenium's Java and Python client to take a screenshot using Selenium WebDriver.
Java Methods
The following are the different Java methods to take a screenshot:
Using getScreenshotAs() from the TakesScreenshot interface:
Code block:
package screenShot;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Firefox_takesScreenshot {
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://login.bws.birst.com/login.html/");
new WebDriverWait(driver, 20).until(ExpectedConditions.titleContains("Birst"));
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(".\\Screenshots\\Mads_Cruz_screenshot.png"));
driver.quit();
}
}
Screenshot:
If the webpage is jQuery enabled, you can use ashot from the pazone/ashot library:
Code block:
package screenShot;
import java.io.File;
import javax.imageio.ImageIO;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;
public class ashot_CompletePage_Firefox {
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://jquery.com/");
new WebDriverWait(driver, 20).until(ExpectedConditions.titleContains("jQuery"));
Screenshot myScreenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(100)).takeScreenshot(driver);
ImageIO.write(myScreenshot.getImage(),"PNG",new File("./Screenshots/firefoxScreenshot.png"));
driver.quit();
}
}
Screenshot:
Using selenium-shutterbug from assertthat/selenium-shutterbug library:
Code block:
package screenShot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import com.assertthat.selenium_shutterbug.core.Shutterbug;
import com.assertthat.selenium_shutterbug.utils.web.ScrollStrategy;
public class selenium_shutterbug_fullpage_firefox {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.google.co.in");
Shutterbug.shootPage(driver, ScrollStrategy.BOTH_DIRECTIONS).save("./Screenshots/");
driver.quit();
}
}
Screenshot:
Python Methods
The following are the different Python methods to take a screenshot:
Using save_screenshot() method:
Code block:
from selenium import webdriver
driver = webdriver.Chrome(r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("http://google.com")
driver.save_screenshot('./Screenshots/save_screenshot_method.png')
driver.quit()
Screenshot:
Using the get_screenshot_as_file() method:
Code block:
from selenium import webdriver
driver = webdriver.Chrome(r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("http://google.com")
driver.get_screenshot_as_file('./Screenshots/get_screenshot_as_file_method.png')
driver.quit()
Screenshot:
Using get_screenshot_as_png() method:
Code block:
from selenium import webdriver
driver = webdriver.Chrome(r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("http://google.com")
screenPnG = driver.get_screenshot_as_png()
# Crop it back to the window size (it may be taller)
box = (0, 0, 1366, 728)
im = Image.open(BytesIO(screenPnG))
region = im.crop(box)
region.save('./Screenshots/get_screenshot_as_png_method.png', 'PNG', optimize=True, quality=95)
driver.quit()
Screenshot:
Ruby (Cucumber)
After do |scenario|
if(scenario.failed?)
puts "after step is executed"
end
time = Time.now.strftime('%a_%e_%Y_%l_%m_%p_%M')
file_path = File.expand_path(File.dirname(__FILE__) + '/../../../../../mlife_screens_shot')+'/'+time +'.png'
page.driver.browser.save_screenshot file_path
end
Given /^snapshot$/ do
time = Time.now.strftime('%a_%e_%Y_%l_%m_%p_%M')
file_path = File.expand_path(File.dirname(__FILE__) + '/../../../../../mlife_screens_shot')+'/'+time +'.png'
page.driver.browser.save_screenshot file_path
end
Ruby
time = Time.now.strftime('%a_%e_%Y_%l_%m_%p_%M_%S')
file_path = File.expand_path(File.dirname(__FILE__) + 'screens_shot')+'/'+time +'.png'
#driver.save_screenshot(file_path)
page.driver.browser.save_screenshot file_path
PHP
public function takescreenshot($event)
{
$errorFolder = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "ErrorScreenshot";
if(!file_exists($errorFolder)){
mkdir($errorFolder);
}
if (4 === $event->getResult()) {
$driver = $this->getSession()->getDriver();
$screenshot = $driver->getWebDriverSession()->screenshot();
file_put_contents($errorFolder . DIRECTORY_SEPARATOR . 'Error_' . time() . '.png', base64_decode($screenshot));
}
}
Java
Using RemoteWebDriver, after augmenting the Node with screenshot capability, I would store the screenshot like so:
void takeScreenShotMethod(){
try{
Thread.sleep(10000);
long id = Thread.currentThread().getId();
BufferedImage image = new Robot().createScreenCapture(new Rectangle(
Toolkit.getDefaultToolkit().getScreenSize()));
ImageIO.write(image, "jpg", new File("./target/surefire-reports/"
+ id + "/screenshot.jpg"));
}
catch( Exception e ) {
e.printStackTrace();
}
}
You may use this method wherever required. Then, I assume you can customize the style sheet of maven-surefire-report-plugin at surefire-reports/html/custom.css so that your reports include the link to the correct screenshot for each test?
Java
String yourfilepath = "E:\\username\\Selenium_Workspace\\foldername";
// Take a snapshort
File snapshort_file = ((TakesScreenshot) mWebDriver)
.getScreenshotAs(OutputType.FILE);
// Copy the file into folder
FileUtils.copyFile(snapshort_file, new File(yourfilepath));
Java
public void captureScreenShot(String obj) throws IOException {
File screenshotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshotFile, new File("Screenshots\\" + obj + "" + GetTimeStampValue() + ".png"));
}
public String GetTimeStampValue()throws IOException{
Calendar cal = Calendar.getInstance();
Date time = cal.getTime();
String timestamp = time.toString();
System.out.println(timestamp);
String systime = timestamp.replace(":", "-");
System.out.println(systime);
return systime;
}
Using these two methods you can take a screen shot with the date and time as well.
Selenese
captureEntirePageScreenshot | /path/to/filename.png | background=#ccffdd
Python
def test_url(self):
self.driver.get("https://www.google.com/")
self.driver.save_screenshot("test.jpg")
It will save a screenshot in the same directory the where script is saved.
You can give a try to AShot API. It is on GitHub.
Examples of tests.
C#
You can use the following code snippet/function to take screenshot with Selenium:
public void TakeScreenshot(IWebDriver driver, string path = #"output")
{
var cantakescreenshot = (driver as ITakesScreenshot) != null;
if (!cantakescreenshot)
return;
var filename = string.Empty + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second + DateTime.Now.Millisecond;
filename = path + #"\" + filename + ".png";
var ss = ((ITakesScreenshot)driver).GetScreenshot();
var screenshot = ss.AsBase64EncodedString;
byte[] screenshotAsByteArray = ss.AsByteArray;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
ss.SaveAsFile(filename, ImageFormat.Png);
}
Java
A method to capture a screenshot for the failures in Selenium with TestName and Timestamp appended.
public class Screenshot{
final static String ESCAPE_PROPERTY = "org.uncommons.reportng.escape-output";
public static String imgname = null;
/*
* Method to Capture Screenshot for the failures in Selenium with TestName and Timestamp appended.
*/
public static void getSnapShot(WebDriver wb, String testcaseName) throws Exception {
try {
String imgpath = System.getProperty("user.dir").concat("\\Screenshot\\"+testcaseName);
File f = new File(imgpath);
if(!f.exists()) {
f.mkdir();
}
Date d = new Date();
SimpleDateFormat sd = new SimpleDateFormat("dd_MM_yy_HH_mm_ss_a");
String timestamp = sd.format(d);
imgname = imgpath + "\\" + timestamp + ".png";
// Snapshot code
TakesScreenshot snpobj = ((TakesScreenshot)wb);
File srcfile = snpobj.getScreenshotAs(OutputType.FILE);
File destFile = new File(imgname);
FileUtils.copyFile(srcfile, destFile);
}
catch(Exception e) {
e.getMessage();
}
}
C# (Ranorex API)
public static void ClickButton()
{
try
{
// code
}
catch (Exception e)
{
TestReport.Setup(ReportLevel.Debug, "myReport.rxlog", true);
Report.Screenshot();
throw (e);
}
}
You can create a webdriverbacked selenium object using the Webdriverclass object, and then you can take a screenshot.
Related
Im trying to decompress a string in java, the string is compress in python with base64 encoding.
I tried a day to resolve the issue, The file can decode easily online and also in python.
Find similar post that people have trouble compressing and decompressing in java and python.
zip.txt
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public class CompressionUtils {
private static final int BUFFER_SIZE = 1024;
public static byte[] decompress(final byte[] data) {
final Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream =
new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[data.length];
try {
while (!inflater.finished()) {
final int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
} catch (DataFormatException | IOException e) {
e.printStackTrace();
log.error("ZlibCompression decompress exception: {}", e.getMessage());
}
inflater.end();
return outputStream.toByteArray();
}
public static void main(String[] args) throws IOException {
decompress(Base64.getDecoder().decode(Files.readAllBytes(Path.of("zip.txt"))));
}
}
Error:
java.util.zip.DataFormatException: incorrect header check
at java.base/java.util.zip.Inflater.inflateBytesBytes(Native Method)
at java.base/java.util.zip.Inflater.inflate(Inflater.java:378)
at java.base/java.util.zip.Inflater.inflate(Inflater.java:464)
Tried also this after #Mark Adler suggestion.
public static void main(String[] args) throws IOException {
byte[] decoded = Base64.getDecoder().decode(Files.readAllBytes(Path.of("zip.txt")));
ByteArrayInputStream in = new ByteArrayInputStream(decoded);
GZIPInputStream gzStream = new GZIPInputStream(in);
decompress(gzStream.readAllBytes());
gzStream.close();
}
java.util.zip.DataFormatException: incorrect header check
at java.base/java.util.zip.Inflater.inflateBytesBytes(Native Method)
at java.base/java.util.zip.Inflater.inflate(Inflater.java:378)
at java.base/java.util.zip.Inflater.inflate(Inflater.java:464)
at efrisapi/com.efrisapi.util.CompressionUtils.decompress(CompressionUtils.java:51)
at efrisapi/com.efrisapi.util.CompressionUtils.main(CompressionUtils.java:67)
That is a gzip stream, not a zlib stream. Use GZIPInputStream.
I was looking in to wrong direction, the string was gzipped, below is the code to resolve it. Thank you #Mark Adler for identifying the issue.
public static void deCompressGZipFile(String gZippedFile, String newFile) throws IOException {
byte[] decoded = Base64.getDecoder().decode(Files.readAllBytes(Path.of(gZippedFile)));
ByteArrayInputStream in = new ByteArrayInputStream(decoded);
GZIPInputStream gZIPInputStream = new GZIPInputStream(in);
FileOutputStream fos = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];
int len;
while ((len = gZIPInputStream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
// Keep it in finally
fos.close();
gZIPInputStream.close();
}
Ok I'm fairly new to swift and am trying to create an app with a button that uses python. I have seem code looking like
//
// ContentView.swift
// Shared
//
// Created by Ulto4 on 10/17/21.
//
import SwiftUI
import PythonKit
struct ContentView: View {
#State private var showDetails = false
#State var result : String = " "
var body: some View {
HStack{
Text("Hello, world!")
.padding()
Button(action : {
self.coolPerson()
}, label: {
Text("Respones")
})
Text("\(result)")
}
}
func coolPerson(){
let sys = Python.import("sys")
sys.path.append("/Users/ulto4/Documents/vsc")
let example = Python.import("ahhhhh")
let response = example.hi()
result = response.description
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.dark)
}
}
The code in the python file is
def hello():
return "cool"
However, when I click the button I get this error
2021-10-17 17:53:16.943097-0700 GAAIN[27059:2277939] PythonKit/PythonLibrary.swift:46: Fatal error: Python library not found. Set the PYTHON_LIBRARY environment variable with the path to a Python library.
(lldb)
I also clicked the .xcodeproj and deleted the Apple Sandbox. But it still doesn't work. Since I'm fairly new I don't know how to do this. Any help would be appreciated.
EDIT: As per the comments, IOS doesn't support PythonKIT
Ok so, let's say I am executing a script with IronPython in C#:
ScriptEngine engine = Python.CreateEngine();
string Script = textBox1.Text();
engine.Execute(Script);
Now let's say the script was:
print("Hello")
Output in VS Console: Hello
What I am trying to achieve here is to redirect that output to a TextBox in C#. I have tried the following method which didn't work:
class TextBoxWriter : TextWriter
{
private RichTextBox _textBox;
public TextBoxWriter(RichTextBox textbox)
{
_textBox = textbox;
}
public override void Write(char value)
{
base.Write(value);
_textBox.AppendText(value.ToString());
}
public override System.Text.Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
Form1_Load:
engine.Runtime.IO.RedirectToConsole();
TextWriter _writer = TextWriter.Synchronized(new TextBoxWriter(textBox1));
Console.SetOut(_writer);
I have just that in my code and its functional for me.
engine.Runtime.IO.RedirectToConsole();
Console.SetOut(new TextBoxWriter(textBox1));
I am trying to communicate to a python script through actionscript. it gives me error on line :
var stdOut:ByteArray = process.standardOutput;
from the function shown below :
public function onOutputData(event:ProgressEvent):void
{
var stdOut:ByteArray = process.standardOutput; //error
var data:String = stdOut.readUTFBytes(process.standardOutput.bytesAvailable);
trace("Got: ", data);
}
Error is:
Implicit coercion of a value with static type IDataInput to a possibly
unrelated type ByteArray.
I am following the same approach as on Adobe's page. Here is some testable code :
package
{
import flash.display.Sprite;
import flash.desktop.NativeProcessStartupInfo;
import flash.filesystem.File;
import flash.desktop.NativeProcess;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
public class InstaUtility extends Sprite
{
public var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
public var file:File = new File("C:/Python27/python.exe");
public var process:NativeProcess = new NativeProcess();
public function InstaUtility()
{
nativeProcessStartupInfo.executable = file;
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory.resolvePath(".");
trace("Location " + File.applicationDirectory.resolvePath(".").nativePath);
var processArgs:Vector.<String> = new Vector.<String>();
processArgs[0] = "test.py";
nativeProcessStartupInfo.arguments = processArgs;
var process:NativeProcess = new NativeProcess();
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
process.start(nativeProcessStartupInfo);
}
public function onOutputData(event:ProgressEvent):void
{
var stdOut:ByteArray = process.standardOutput; //error
var data:String = stdOut.readUTFBytes(process.standardOutput.bytesAvailable);
trace("Got: ", data);
}
}
}
The NativeProcess could not be started. Not supported in current
profile.
Are you testing in Flash IDE?
Test within IDE : In your AIR Publish Settings make sure you ticked only "extended Desktop" when debugging through IDE. This way you also get traces etc.
Test after Publish : You must tick both "Desktop" and "extended Desktop" and also tick "Windows Installer (.exe)". Install your App using the generated .exe file (not the .air file).
Implicit coercion of a value with static type IDataInput to a possibly
unrelated type ByteArray.
var stdOut:ByteArray = process.standardOutput; //error is not how it's done!! Don't make any var each time the progress event fires up. Each firing holds around 32kb or 64kb of bytes only (can't remember), so if the expected result is larger it will continue to fire in multiple chunks... Use and recycle a single public byteArray to hold all the result data.
Try a setup like below :
//# Declare the public variables
public var stdOut : ByteArray = new ByteArray();
public var data_String : String = "";
Your process also needs a NativeProcessExitEvent.EXIT listener.
process.addEventListener(NativeProcessExitEvent.EXIT, on_Process_Exit );
Before you .start a process, also clear the byteArray ready for new data with stdOut.clear();.
Now your progressEvent can look like this below... (Process puts result data into stdOut bytes).
public function onOutputData (event:ProgressEvent) : void
{
//var stdOut:ByteArray = process.standardOutput; //error
//# Progress could fire many times so keep adding data to build the final result
//# "stdOut.length" will be zero at first but add more data to tail end (ie: length)
process.standardOutput.readBytes( stdOut, stdOut.length, process.standardOutput.bytesAvailable );
//# Below should be in a Process "Exit" listener but might work here too
stdOut.position = 0; //move pointer back before reading bytes
data_String = stdOut.readUTFBytes( stdOut.length );
trace("function onOutputData -- Got : " + data_String );
}
But you really need to add an "onProcessExit" listener and then only check for results when the process itself has completed. (Tracing here is much safer for a guaranteed result).
public function on_Process_Exit (event : NativeProcessExitEvent) : void
{
trace ("PYTHON Process finished : ############# " )
stdOut.position = 0; //# move pointer back before reading bytes
data_String = stdOut.readUTFBytes( stdOut.length );
trace("PYTHON Process Got : " + data_String );
}
I'm trying open a file in Eclipse editor from my python program.
Here is example how to do this with Java:
import java.io.File;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
File fileToOpen = new File("externalfile.xml");
if (fileToOpen.exists() && fileToOpen.isFile()) {
IFileStore fileStore = EFS.getLocalFileSystem().getStore(fileToOpen.toURI());
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
IDE.openEditorOnFileStore( page, fileStore );
} catch ( PartInitException e ) {
//Put your exception handler here if you wish to
}
} else {
//Do something if the file does not exist
}
I'm trying to use this API from python with use of Py4j.
from py4j.java_gateway import JavaGateway, java_import
gateway = JavaGateway()
jvm = gateway.jvm
java_import(jvm, 'org.eclipse.core.filesystem.EFS')
java_import(jvm, 'org.eclipse.ui.PlatformUI')
fileToOpen = jvm.java.io.File('c:/test.txt')
fileStore = jvm.org.eclipse.core.filesystem.EFS.getLocalFileSystem().getStore(fileToOpen.toURI());
This works fine. But I have stacked with getting page.
page = jvm.org.eclipse.ui.PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
I'm getting None here. Looks like Rudolf Widmann have posted answer for this question here. So the java solution will be:
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
IWorkbenchWindow iw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
}
});
But how can I do this from python? How to implement it with Py4j?
Did you try to implement the Runnable interface in Python?
class PythonRunner(object):
def __init__(self, gateway):
self.gateway = gateway
self.iw
def run(self):
self.iw = gateway.jvm.org.eclipse.ui.PlatformUI.getWorkbench().getActiveWorkbenchWindow()
class Java:
implements = ['java.lang.Runnable']
gateway = JavaGateway(start_callback_server=True)
runner = PythonRunner(gateway)
gateway.jvm.org.eclipse.swt.widgets.Display.getDefault().asyncExec(runner)
# Replace with a synchronization primitive
time.sleep(2)
page = runner.iw.getActivePage()