All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sitoolkit.tester.domain.test.OperationLog Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013 Monocrea Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sitoolkit.tester.domain.test;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.sitoolkit.core.infra.util.SitFileUtils;
import org.sitoolkit.tester.infra.SitPathUtils;
import org.sitoolkit.tester.infra.TestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

/**
 * このクラスは、テストの操作ログを表すリポジトリです。
 * 操作ログは、カレントディレクトリ以下に以下の階層で出力します。
 * 
 * +- opelog_yyyyMMddhhmmss
 *    +- img
 *       +- case_nnn_mmm_itemName.png
 *    +- case_nnn.html
 * 
* * @author yuichi.kuwahara */ @Component public class OperationLog { @Resource TestContext current; private static final Logger LOG = LoggerFactory.getLogger(OperationLog.class); private List records = new ArrayList(); /** * 操作ログのVelocityテンプレート */ private String templatePath = "/opelog/opelog-template.vm"; /** * 操作ログの表示に関連する資源 */ private String[] opelogResources = new String[] { "classpath:opelog/style.css", "classpath:opelog/jquery.js", "classpath:opelog/numbering.js" }; /** * 操作ログの出力先ディレクトリ */ private File opelogRootDir; /** * スクリーンショットの出力先ディレクトリ */ private File imgDir; private String logFilePath = "target/sit-wt.log"; private List positionList = new ArrayList(); private Template tmpl; @PostConstruct public void init() { opelogRootDir = new File("target", "opelog_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); opelogRootDir.mkdirs(); if (opelogRootDir.exists()) { LOG.info("操作ログ出力ディレクトリを作成しました。{}", opelogRootDir.getAbsolutePath()); } else { throw new TestException("操作ログ出力ディレクトリの作成に失敗しました" + opelogRootDir.getAbsoluteFile()); } imgDir = new File(opelogRootDir, "img"); imgDir.mkdirs(); if (!imgDir.exists()) { throw new TestException("スクリーンショット出力ディレクトリの作成に失敗しました" + imgDir.getAbsoluteFile()); } try { Properties prop = SitFileUtils.resource2prop(getClass(), "/velocity.properties"); Velocity.init(prop); tmpl = Velocity.getTemplate(templatePath); for (String opelogRes : getOpelogResources()) { URL url = ResourceUtils.getURL(opelogRes); File dstFile = new File(opelogRootDir, StringUtils.substringAfterLast(url.getPath(), "/")); FileUtils.copyURLToFile(url, dstFile); } } catch (IOException e) { throw new TestException(e); } } /** * 定型メッセージで操作ログを出力します。 * @param log ロガー * @param verb ログメッセージの動作を表す単語 * @param pos */ public void info(Logger log, String verb, ElementPosition pos) { info(log, pos, "{}({})を{}します", current.getTestStep().getItemName(), current.getTestStep().getLocator(), verb); } /** * 定型メッセージで操作ログを出力します。 * @param log ロガー * @param object ログメッセージの目的語 * @param verb ログメッセージの動作を表す単語 * @param pos */ public void info(Logger log, String object, String verb, ElementPosition pos) { info(log, pos, "{}({})に[{}]を{}します", current.getTestStep().getItemName(), current.getTestStep().getLocator(), object, verb); } public void info(Logger log, ElementPosition pos, String messagePattern, Object... params) { String msg = MessageFormatter.arrayFormat(messagePattern, params).getMessage(); outLogAndAddRecord(log, msg, pos, LogLevelVo.INFO); } public void warn(Logger log, String messagePattern, Object... params) { String msg = MessageFormatter.arrayFormat(messagePattern, params).getMessage(); outLogAndAddRecord(log, msg, null, LogLevelVo.WARN); } void outLogAndAddRecord(Logger log, String msg, ElementPosition pos, LogLevelVo logLevel) { LogRecord record = new LogRecord(); switch (logLevel) { case DEBUG: log.debug(msg); break; case INFO: log.info(msg); break; case WARN: log.warn(msg); break; case ERROR: log.error(msg); break; default: // NOP } record.setLogLevel(logLevel); record.setNo(current.getTestStep().getNo()); record.setLog(msg); records.add(record); addPosition(pos); } public void addPosition(ElementPosition pos) { if (pos != null && pos != ElementPosition.EMPTY) { pos.setNo(current.getTestStep().getNo()); positionList.add(pos); } } /** * 操作ログにスクリーンショットを追加します。 * @param file スクリーンショットの画像ファイル * @see #addScreenshot(java.io.File, java.lang.String, boolean) */ public void addScreenshot(File file) { addScreenshot(file, ""); } /** * 操作ログにスクリーンショットを追加します。 * @param file スクリーンショットの画像ファイル * @param timing スクリーンショット取得タイミング ファイル名に使用する。 * @see #addScreenshot(java.io.File, java.lang.String, boolean) */ public void addScreenshot(File file, String timing) { addScreenshot(file, timing, true); } /** * 操作ログにスクリーンショットを追加します。 * @param file スクリーンショットの画像ファイル * @param timing スクリーンショット取得タイミング ファイル名に使用する。 * @param withPos 操作ログを表示した際に、要素位置を表示する場合にtrueを指定 */ public void addScreenshot(File file, String timing, boolean withPos) { if (file == null) { renewPositionList(); return; } File dstFile = new File(imgDir, screenshotFileName( current.getScriptName(), current.getCaseNo(), current.getTestStepNo(), current.getItemName(), timing)); try { if (dstFile.exists()) { dstFile = new File(imgDir, dstFile.getName() + "_" + System.currentTimeMillis()); } FileUtils.moveFile(file, dstFile); LogRecord record = new LogRecord(); record.setFilePath(SitPathUtils.relatvePath(opelogRootDir, dstFile)); record.setLog(dstFile.getName()); if (withPos) { record.setPositions(positionList); } records.add(record); LOG.info("スクリーンショットを取得しました {}", dstFile.getAbsolutePath()); } catch (IOException e) { LOG.warn("スクリーンショットファイルの移動に失敗しました", e); } } String screenshotFileName(String scriptName, String caseNo, String testStepNo, String itemName, String timing) { return StringUtils.join( new String[] { scriptName, caseNo, testStepNo, itemName, timing }, "_") + ".png"; } String opelogFileName(String scriptName, String caseNo) { String resultHtml = ".html"; if (hasError()) { resultHtml = "_NG.html"; } return StringUtils.join( new String[] { scriptName, caseNo }, "_") + resultHtml; } /** * 位置情報のリストを再作成します。 */ public void renewPositionList() { positionList = new ArrayList(); } public void flush() { File htmlFile = new File( opelogRootDir, opelogFileName(current.getScriptName(), current.getCaseNo())); if (htmlFile.exists()) { htmlFile = new File(htmlFile.getParent(), System.currentTimeMillis() + "_" + htmlFile.getName()); } LOG.info("操作ログを出力します {}", htmlFile.getAbsolutePath()); try { String evidence = build(current.getCaseNo()); FileUtils.write(htmlFile, evidence, "UTF-8"); } catch (Exception e) { throw new TestException("操作ログの出力に失敗しました", e); } finally { records.clear(); renewPositionList(); } } public void moveLogFile() { try { File logFile = new File(getLogFilePath()); FileUtils.copyFileToDirectory(logFile, opelogRootDir, true); logFile.deleteOnExit(); } catch (IOException e) { throw new TestException(e); } } /** * 操作ログファイルに出力する文字列を構築します。 * * @return 操作ログファイルに出力する文字列 */ String build(String caseNo) { VelocityContext context = new VelocityContext(); StringWriter writer = new StringWriter(); context.put("opeLog", this); context.put("caseNo", caseNo); context.put("testScriptName", current.getScriptName()); context.put("result", (hasError()) ? "NG" : ""); tmpl.merge(context, writer); return writer.toString(); } public List getRecords() { return Collections.unmodifiableList(records); } /** * エラーログを出力します。 */ void error(Logger log, String msg) { LogRecord record = new LogRecord(); log.error(msg); record.setNo(current.getTestStepNo()); record.setLog(msg); record.setLogLevel(LogLevelVo.ERROR); records.add(record); } boolean hasError() { for (LogRecord logRecord : records) { if (LogLevelVo.ERROR.equals(logRecord.getLogLevel())) { return true; } } return false; } public String getLogFilePath() { return logFilePath; } public void setLogFilePath(String logFilePath) { this.logFilePath = logFilePath; } public String getTemplatePath() { return templatePath; } public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } public String[] getOpelogResources() { return opelogResources; } public void setOpelogResources(String[] opelogResources) { this.opelogResources = opelogResources; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy