Selenium WebDriverの画面キャプチャ 拡張子を変える

Selenium WebDriverでキャプチャを撮って、画像ファイルに保存するときに拡張子をjpeg、giff、pngなど変えるやり方。

普通にキャプチャをファイルに保存するには

public void takeScreenShot(Path outputPath) {
    System.out.println("= Screen Shot =");
    File img = ((TakesScreenshot)this.webDriverInstance).getScreenshotAs(OutputType.FILE);
    try {
        FileUtils.copyFile(img, outputPath.toFile());
        System.out.println("Name : " + outputPath.toFile().getAbsolutePath());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

selenium-javaの依存関係にcommons-ioが入っているので、特別追加しなくてもFileUtilsを使える。

画像の拡張子を指定して画像保存する

    /**
     * 起動済みのブラウザでスクリーンショットを撮る。
     */
    public void takeScreenShot(Path outputPath) {
        System.out.println("= Screen Shot =");
        File img = ((TakesScreenshot)this.webDriverInstance).getScreenshotAs(OutputType.FILE);
        try {
            FileUtils.forceMkdirParent(outputPath.toFile());
            ImageIO.write(ImageIO.read(img), "jpeg", outputPath.toFile());
            System.out.println("Name : " + outputPath.toFile().getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

javax.imageio.ImageIOクラスで以下の拡張子に対応してるらしい。

WriterFormatNames:
BMP
bmp
jpeg
wbmp
png
JPG
PNG
jpg
WBMP
JPEG

参考

stackoverflow.com

www.javadrive.jp

typesafe/Config ConfigBeanFactoryの良さそうな使い方

設定ファイルを扱いたくて、イマドキどんな形式が良いんだろうなと調べてみたら、 typesafe/ConfigというライブラリでHOCONというファイル形式があるらしい。

紹介記事や簡単な使い方については、以下を参照。

Java アプリケーションのための設定ファイル形式の比較

Play Frameworkでも使われているコンフィグライブラリが非常に便利


で、

結論から言うと、 ConfigBeanFactory使うなら、typesafe/Config + lombok が良さそう!


typesafe/Configで、version 1.3から追加されたらしいConfigBeanFactoryクラスを使ってみた。

https://github.com/typesafehub/config#configbeanfactory

自作のjava beanクラス AppConfigを生成させている。

    /**
     * application.confを読み込み、Beanで返す。
     * @return AppConfig
     */
    public static AppConfig getConfig() {
        return ConfigBeanFactory.create(load(), AppConfig.class);
    }

読み込ませたい設定ファイルは、こんな感じで、

webdriver {
    chrome=/usr/local/bin/chromedriver
    ie=/usr/local/bin/iedriver
    firefox=/usr/local/bin/firefoxdriver
}
output{
    dirpath=.
    caseid=case
    image{
        extension=jpg
    }
}
browser{
    width=300
    height=300
}

AppConfigクラスはこんな感じで、フィールド名と設定ファイルのkeyが一致している必要がある。
またフィールドに対応するgetter/setterを記述する必要があるが、
そこをlombokで生成(ここでは @Data)してあげることで、
簡易にConfigBeanを実装することが出来ている。

import lombok.Data;

@Data
public class AppConfig {
    private WebDriverConf webdriver;
    private OutputConf output;
    private BrowserConf browser;
}

フィールドの型はこんな風にネストしてBeanを使うことも可能。

import lombok.Data;

@Data
public class WebDriverConf {
    private String chrome;
    private String ie;
    private String firefox;
}

その他のクラスはgithubにおいてあります。

github.com


個人的にはConfigBeanを作ることで、設定のkeyを管理しなくて良くなったので嬉しかった。

でも欠点は、ConfigBeanの値を変更して設定ファイルに保存(シリアライズ)したい時に、typesafeのConfigやConfigObjectに再変換するのが大変なこと。 たぶん地道にMapにpushするみたく、withValueメソッドを呼びまくらないといけない。

少し調べてstackoverflowのどこかのページで、「typesafe/Configはimmutableな設定を扱うツールだよ :)」とあり、設定の変更はあんまりやらない思想なのかな?ということで諦めモード。

一応config.root().render()シリアライズされた文字列が返るので、それをファイルに保存してやれば良い。
ConfigObjectクラスのrenderメソッド

docpressをつかってみた

https://clashm45.github.io/electron-twitter-client/docpress-configuration.html f:id:clash_m45:20160910205957p:plain

docpress Configuration

docpressのサンプルはキレイな色使いがされていますが、デフォルトでは白黒のみです。
docpressの作者よりcssが提供されているので、それを参照するようにしてあげると同じ色使いになります。

docpressの設定はdocpress.jsonに書きます。

docpress.json
{
  "css": [
    "http://ricostacruz.com/docpress-rsc/style.css",
    "docs/assets/custom.css"
  ],
  "markdown": {
    "typographer": true,
    "plugins": {
      "decorate": {},
      "emoji": {}
    }
  },
  "plugins": {
    "docpress-core": {},
    "docpress-base": {}
  }
}

すこしの手間でキレイにHTML化して見栄えの良いサイトになるので、よさ気ですゼ

plugins

docpressはmarkdownの装飾やコンポーネントの追加に、markdown-itを冠したパッケージを導入できるみたいです。

markdown-it-emojiを導入してみました。

:smile:

> Classic markup: :wink:  :cry:  :laughing:  :yum:
>
> Shortcuts (emoticons): :-) :-( 8-) ;)

f:id:clash_m45:20160910210315p:plain

twitter client for electronを写経してみた

WEB+DB PRESS vol.94の "作って学ぶElectron Webの技術でデスクトップアプリ!” を実践したコードをgithubで公開しました。

github.com

ソースコードはgihyo.jpの記事サポートページに公開されています。
コメントが書かれてないので、記事を読まないと初心者には理解できないと思います。

このプロジェクトもほぼ同じコードとなっていますが、自分なりのコメントを追加しています。

作って学ぶElectron Webの技術でデスクトップアプリ!

Electronを利用すると,JavaScript,HTML,CSSなどWebの技術を利用してデスクトップアプリを作成できます。 GitHubが開発していて,Atomエディタに使われているほか,Visual Studio Codeなどにも利用されています。 本特集では,実際にElectronを使ってアプリを開発しているエンジニアにより,Electronの基礎知識からはじめ,実際にサンプルアプリを作成して主要なAPIの使い方,デバッグ/テスト手法,そしてアプリを配布するための手順まで解説します。

Build

Node.jsと、デスクトップ・アプリケーションを作成できるNode.jsフレームワークElectronを使って作成します。

Electronは、JavaScriptとHTMLで実装します。 HTMLコンポーネントを作成するReactフレームワークも使います。

Dependencies

  • "babel-plugin-transform-react-jsx": "^6.8.0",
  • "babel-register": "^6.14.0",
  • "photon": "git+https://github.com/connors/photon.git",
  • "react": "^15.3.1",
  • "react-dom": "^15.3.1",
  • "twit": "^2.2.4"

パッケージのversionに"^"が入っている場合は、最新にアップデートされるらしいです。
実際に開発して公開などする場合は、固定のバージョンを指定するようにしたほうが良さそうです。

Build command

npmで依存パッケージをDLできます。 docpressも依存に追加しているのでDLされます。

npm i

実行コマンド

package.jsonに記述していますが、npmのscripts設定からelectronを起動しています。

npm run start

Document

ついでにdocpressというMarkdownで書くwebsite generatorが紹介されていたので、ドキュメントに使ってみました。

https://clashm45.github.io/electron-twitter-clientclashm45.github.io f:id:clash_m45:20160910203717p:plain

Impressions

ちょうど個人的にElectronを勉強してたところでした。
この記事は、Node.jsとそのパッケージ管理ソフトnpmも、React.jsも実践できるのでいい教材です。

Electronはそう難しくなく、むしろReactの挙動を理解するまでが大変。

以上

Marp使ってみた

Marpというmarkdownでスライドが書けるエディタがリリースされていたのを見つけ、早速使ってみました。

 

使いやすすぎてめちゃ感動したので、スライド作って上げてみたくなり、ちょっとした(ほんとにちょっと)紹介スライド書きました。

 

 

 
個人的には、
  • 日本語に対応してる
  • 絵文字も使える!
 ってのがすごい良かったです。
 
 
こういうのって迷惑だったりするのかなー

PrimeFacesを試してみる - p:layout

PrimeFacesを試してみる - p:layout

PrimeFacesを研究しよう!と思い、PrimeFaces Showcaseをマネして作ってみようと思います。

開発環境については、環境構築編で書いたやつに追加していく感じです。

githubに公開しました

PrimeFaces Showcaseを作っていく

作っていくわけですが、まずはレイアウトを作ります。
showcaseを見てみると、こんな感じのレイアウトです。 f:id:clash_m45:20150510235553p:plain

showcaseのソースコードも公開されていて、どうやってサイドメニュー作ってるのかな~って見てみたんですが...

<h:body>

    <!-- PC CONTENT STARTS HERE-->
    <div class="PC">
        
    <div id="MENUSIDE">
        <div id="MENUSIDEindent">
            <span id="LOGO" class="bordersOfMenuSide">
                <h:graphicImage name="main/images/logo.svg" />
                <h:graphicImage id="BlueLogo" styleClass="hiddenLogo" name="main/images/logoBlue.svg" />
            </span>
  • showcase-5.2/resources/main/css/showcase.css
 /* menu side style*/
    #MENUSIDE{width:85px; float:left; background-color:#313b3f; border-right:solid 1px #151d21; overflow:hidden; width: 300px; position: fixed;}
        #MENUSIDEindent{width:100%; height:auto;}
            #LOGO{height:87px; display:block; padding:27px 0 5px 10px; z-index:997; background-color:#313b3f;margin-left:100px}
                #LOGO img{width:62px; height:auto; }

なーんか普通にCSSでゴリってる感じですわ。

CSSが苦手!!な私はほぼ全てJSFで作ってみようと思います。

p:layout と p:layoutunit

JSFでは画面のテンプレートを作ることが出来ます。
そのテンプレートのレイアウトにPrimeFacesのp:layoutを使っていきます。

3.62 Layout
Layout component features a highly customizable borderLayout model making it very easy to create complex layouts even if you’re not familiar with web design.

[google先生]
レイアウトコンポーネントは、することが非常に容易になり、高度なカスタマイズのBorderLayoutモデルを提供しています
あなたはWebデザインに慣れていない場合でも、複雑なレイアウトを作成します。

p:layoutの中にp:layoutunitを入れて、p:layoutunitのpositionに

  • north
  • south
  • west
  • east
  • center

を設定することで、こんな感じでレイアウト配置してくれるコンポーネントです。

f:id:clash_m45:20150511001224j:plain

  • 上の例のHTML
<p:layout fullPage="true">

    <p:layoutUnit position="north" size="100" header="Top" >
        <h:outputText value="North unit content." />
    </p:layoutUnit>
 
    <p:layoutUnit position="south" size="100" header="Bottom">
        <h:outputText value="South unit content." />
    </p:layoutUnit>
 
    <p:layoutUnit position="west" size="200" header="Left">
        <h:outputText value="West unit content." />
    </p:layoutUnit>
 
    <p:layoutUnit position="east" size="200" header="Right">
        <h:outputText value="Right unit content." />
    </p:layoutUnit>
 
    <p:layoutUnit position="center">
        //page code
    </p:layoutUnit>
 
</p:layout>

JSF Templateをp:layoutで作っていく

出来ました。

f:id:clash_m45:20150510235629p:plain

p:layoutはネストすることも出来ます。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <title><ui:insert name="title">Hello Java EE</ui:insert></title>
</h:head>

<h:body>
    <ui:debug hotkey="x"
        rendered="#{initParam['javax.faces.FACELETS_DEVELOPMENT']}" />

    <p:layout fullPage="true">

        <p:layoutUnit position="west" size="200" header="sidemenu">
            <ui:insert name="sidemenu">
                <!-- <ui:include src="header.xhtml"/> -->
                Side Menu area.
            </ui:insert>
        </p:layoutUnit>

        <p:layoutUnit position="center">
            <p:layout>
                <p:layoutUnit position="north" size="200" header="content header">
                    <ui:insert name="content-header">
                        Content Header area.
                    </ui:insert>
                </p:layoutUnit>

                <p:layoutUnit position="center" header="content">
                    <ui:insert name="content">
                        Content area.
                    </ui:insert>
                </p:layoutUnit>
            </p:layout>

        </p:layoutUnit>

    </p:layout>

</h:body>

</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<ui:composition template="/template/template.xhtml">
    <ui:define name="content">
        <h1>Hello World!!</h1>

        <h:outputLabel value="JSF world" />

        <p:spinner />
    </ui:define>
</ui:composition>
</html>

もしうまく動かなかったら、ブラウザのデバッグ機能で確認したり、あとは<h:body>とかがちゃんと使われてるかを確認して下さい。


p:layoutunitのオプションを説明

いろいろオプション属性を付けることでカッコよくなります。

resizable

レイアウトのサイズをマウスで変更出来る。

<p:layout>
    <p:layoutUnit position="north" size="200" header="content header" resizable="true" >

f:id:clash_m45:20150510235650p:plain

closable

レイアウトを閉じる。
でも閉じたら戻ってこない?

<p:layoutUnit position="west" size="200" header="sidemenu" closable="true" >

f:id:clash_m45:20150510235706p:plain

collapsible

レイアウトを畳む。 畳んだあと、開くボタンも出てきます。

<p:layoutUnit position="north" size="200" header="content header" collapsible="true" >

f:id:clash_m45:20150510235717p:plain

gutter

溝のサイズを指定するらしい。
なんかあんまりうまく動作してない・・・?

<p:layoutUnit position="center" header="content" gutter="0">

f:id:clash_m45:20150510235733p:plain

collapsed , collapseSize

collapsibleの状態を設定するものみたいです。
collapsed="true"だと最初から畳んだ状態で表示。
collapseSizeは閉じた時のサイズを指定する。

<p:layoutUnit position="north" size="200" header="content header" 
    collapsible="true" collapsed="true" collapseSize="100">

つーことで、templateが出来ました。
JSF templateはすごい使いやすくて、コンテンツのページはすごい記述が少なくて済むので嬉しくなります。

PrimeFacesのp:layoutCSSが苦手な私でもレイアウトが簡単に出来ました!

終わり。

PrimeFacesを試してみる - 環境構築編

PrimeFacesを試してみる - 環境構築編

githubに公開しました

環境:

1. プロジェクト作成

Gradleプロジェクトを作る。 f:id:clash_m45:20150510134912p:plain

gradle war pluginではweb系のファイルはsrc/main/webappに置くみたいなので、手動でソース・フォルダを作成します。
すると以下のようなフォルダ構成になります。

helloJavaEE
└─src
   ├─main
   │  ├─java
   │  ├─resources
   │  └─webapp
   │      └─WEB-INF
   └─test
       ├─java
       └─resources

2. build.gradle

gradleでJava EE構成したことなかったので、調べてみたらmaven repositoryはあるみたいっすね。

いらん記述を消して、以下build.gradleにしました。

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile(
        'commons-collections:commons-collections:3.2',
        'javax:javaee-api:7.0'
    )

    testCompile 'junit:junit:4.+'
}

3. index.xhtmlを作る

ここまででプロジェクトは出来たはずなので、index.xhtmlを書いてブラウザで表示してみます。

[新規] - [Web] - [HTMLファイル]でJSFテンプレート有りのxhtmlが作成できます。 f:id:clash_m45:20150510134918p:plain

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<h:head>
    <title>Hello Java EE</title>
</h:head>
<h:body>

<h1>Hello World!!</h1>

<h:outputLabel value="JSF world" />

</h:body>
</html>

4. web.xmlを作る

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.faces</welcome-file>
    </welcome-file-list>
</web-app>

ファイル構成はこんな感じになりました。

helloJavaEE
└─src
    ├─main
    │  ├─java
    │  ├─resources
    │  └─webapp
    │      │  index.xhtml
    │      │
    │      └─WEB-INF
    │              web.xml
    │
    └─test
        ├─java
        └─resources

5. Glassfishへデプロイ!

動いた~

f:id:clash_m45:20150510135005p:plain

補足. gradleでglassfishにデプロイする

毎回gradle warしてglassfishにデプロイするの面倒だな~と思ったら出来ました。

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile(
        'commons-collections:commons-collections:3.2',
        'javax:javaee-api:7.0'
    )

    testCompile 'junit:junit:4.+'
}

ext {
    glassFishHome = 'C:/glassfish-4.1/glassfish4'
    asadmin = glassFishHome + (isWindows() ? '/bin/asadmin.bat'
                                           : '/bin/asadmin')
    domain = 'domain1'
}

def isWindows() {
    return System.properties['os.name'].toLowerCase().contains('windows')
}

task startServer(type: Exec) {
    commandLine asadmin, 'start-domain', '--debug=true', domain
}

task stopServer(type: Exec) {
    commandLine asadmin, 'stop-domain', domain
}

task deploy(type: Exec, dependsOn: 'war') {
    commandLine asadmin, 'deploy', '--force=true', war.archivePath
}

ほんで、eclipsegradle タスクビューを開いて、ポチポチっとするとデプロイ出来るようになりました。

f:id:clash_m45:20150510135019p:plain

デバッグeclipseの[デバッグの構成] - [リモートJavaアプリケーション]で実行できるようです。(まだ試してない)

6. Primefacesを試す

タイトルがPrimeFacesだったのを思い出しました。

build.gradleにPrimeFacesの依存関係を追加します。

dependencies {
    compile(
        'commons-collections:commons-collections:3.2',
        'javax:javaee-api:7.0',
        'org.primefaces:primefaces:5.2'
    )

    testCompile 'junit:junit:4.+'
}

試す!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:head>
    <title>Hello Java EE</title>
</h:head>
<h:body>

<h1>Hello World!!</h1>

<h:outputLabel value="JSF world" />

<p:spinner />

</h:body>
</html>

どや~ f:id:clash_m45:20150510135034p:plain