|
使用watir做自动化测试时,当脚本执行过程中出现验证失败时,有时需要进行截图保存
其实watir自带了截图的功能,自带的方法在下面目录:
C:\ruby\lib\ruby\gems\1.8\gems\watir-1.6.2\lib\watir\screen_capture.rb
原理:
1、模拟键盘输入截图按键
2、打开windows自带的画图软件,将黏贴板中截图的信息复制到画图软件中
3、保存为JPG或 BMP格式
因为自带的方法不完全符合实际测试的要求,修改了下,增加了下面内容:
1、增加对相对路径的支持,如:"# {File.dirname(__FILE__)}/http://www.cnblogs.com/input/test.jpg"
2、当路径不存在时,创建相应的目录
3、当目录中已存在对应文件时,先重命名存在的文件,重命名后的文件如:test.20090812151922.jpg
修改后的类(LibScreen.rb)如下:
LibScreen.rb
class ScreenClass
def initialize
require 'Win32API'
end
#功能说明:
#- 将文件重命名
#
#参数说明:
#- from:原文件路径,必须带文件名,格式如:c:\\test.txt
#- to:新文件路径及名称,必须带文件名,格式如:c:\\test_bak.txt,不带该参数时,默认在原文件名后加上日期
#
#调用示例:
#- $TxtClass.RenameFile("c:\\test.txt","c:\\test_bak.txt")
#- $TxtClass.RenameFile("c:\\test.txt")
#
#返回值说明:
#- 成功:返回true
#- 失败:返回false
def RenameFile(from,to = nil)
begin
if (FileTest::exist?(from)) and (File.basename(from) =~ /.*\..*/ )
if (to == nil)
extname = File.extname(from)
filename = File.basename(from,extname)
new_filename = filename + '.' + Time.now.strftime("%Y%m%d%H%M%S") + extname
to = File.dirname(from) + '/'+ new_filename
end
File.rename(from, to)
return true
else
puts "重命名文件失败,原因:文件不存在,路径为#{from}"
return false
end
rescue StandardError => bang
puts "Error running script: " + bang
return false
end
end
#功能说明:
#- 获取文件的真实路径
#
#参数说明:
#- file_path:原文件路径,如果原文件路径不存在,系统自动创建相应路径
#- return_file:是否返回路径中的文件名,默认未返回
#
#调用示例:
#- $TxtClass.GetRealPath("#{File.dirname(__FILE__)}/http://www.cnblogs.com/input/data.xls" )
#
#返回值说明:
#- 成功:返回真实的路径
#- 失败:返回false
def GetRealPath(file_path,return_file = 'Y')
begin
@@file_name = ''
@@real_dir_row = []
if (file_path.include?("\\"))
file_path = file_path.to_s.gsub('\\','/')
end
if (file_path.include?("/"))
file_basename = File.basename(file_path) #获取文件名
file_dirname = File.dirname(file_path)
if (file_basename =~ /.*\..*/)
file_dirname = File.dirname(file_path)
else
file_basename = ''
file_dirname = file_path
end
if (!FileTest::exist?(file_dirname)) #判断目录是否存在,不存在则创建相应目录
FileUtils.makedirs(file_dirname)
end
if (file_dirname[0,2] == './')
real_dir = Pathname.new(File.dirname(File.dirname(file_dirname[0,2]))).realpath
real_path = File.join(real_dir,file_dirname[2,file_dirname.length] )
else
real_path = file_dirname
end
if (real_path.include?(".."))
temp_row = real_path.split('/')
temp_row.each do |dir|
if(dir == "..")
@@real_dir_row.pop
else
@@real_dir_row.push(dir)
end
end
real_path = @@real_dir_row.join('/')
end
if (return_file.upcase == 'Y')
result = File.join(real_path,file_basename)
else
result = real_path
end
result = result.to_s.gsub('/','\\')
return result
else
puts "获取文件路径失败,原因:#{real_path}路径格式不正确。"
return false
end
rescue StandardError => bang
puts "Error running script: " + bang
return false
end
end #def GetRealPath
def ScreenCapture(file_path , active_window_only=false, save_as_bmp=false)
keybd_event = Win32API.new("user32", "keybd_event", ['I','I','L','L'], 'V')
vkKeyScan = Win32API.new("user32", "VkKeyScan", ['I'], 'I')
winExec = Win32API.new("kernel32", "WinExec", ['P','L'], 'L')
openClipboard = Win32API.new('user32', 'OpenClipboard', ['L'], 'I')
setClipboardData = Win32API.new('user32', 'SetClipboardData', ['I', 'I'], 'I')
closeClipboard = Win32API.new('user32', 'CloseClipboard', [], 'I')
globalAlloc = Win32API.new('kernel32', 'GlobalAlloc', ['I', 'I'], 'I')
globalLock = Win32API.new('kernel32', 'GlobalLock', ['I'], 'I')
globalUnlock = Win32API.new('kernel32', 'GlobalUnlock', ['I'], 'I')
memcpy = Win32API.new('msvcrt', 'memcpy', ['I', 'P', 'I'], 'I')
file_basename = File.basename(file_path) #获取文件名
if(file_basename.upcase =~ /.*.(JPG|BMP)/)
real_file_path = GetRealPath(file_path) #获取文件的真实路径
if (FileTest::exist?(real_file_path))
RenameFile(real_file_path)
end
if active_window_only ==false
keybd_event.Call(0x2C,0,0,0) # Print Screen
else
keybd_event.Call(0x2C,1,0,0) # Alt+Print Screen
end
winExec.Call('mspaint.exe', 5)
sleep(1)
# Ctrl + V : Paste
keybd_event.Call(0x11, 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?V), 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?V), 1, 0X2, 0)
keybd_event.Call(0x11, 1, 0X2, 0)
# Alt F + A : Save As
keybd_event.Call(0x12, 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?F), 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?F), 1, 0X2, 0)
keybd_event.Call(0x12, 1, 0X2, 0)
keybd_event.Call(vkKeyScan.Call(?A), 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?A), 1, 0X2, 0)
sleep(1)
# copy filename to clipboard
hmem = globalAlloc.Call(0X0002, real_file_path.length+1)
mem = globalLock.Call(hmem)
memcpy.Call(mem, real_file_path, real_file_path.length+1)
globalUnlock.Call(hmem)
openClipboard.Call(0)
setClipboardData.Call(1, hmem)
closeClipboard.Call
sleep(1)
# Ctrl + V : Paste
keybd_event.Call(0x11, 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?V), 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?V), 1, 0X2, 0)
keybd_event.Call(0x11, 1, 0X2, 0)
if save_as_bmp == false
# goto the combo box
keybd_event.Call(0x09, 1, 0, 0)
keybd_event.Call(0x09, 1, 0X2, 0)
sleep(0.5)
# select the first entry with J
keybd_event.Call(vkKeyScan.Call(?J), 1, 0, 0)
keybd_event.Call(vkKeyScan.Call(?J), 1, 0X2, 0)
sleep(0.5)
end
# Enter key
keybd_event.Call(0x0D, 1, 0, 0)
keybd_event.Call(0x0D, 1, 0X2, 0)
sleep(1)
# Alt + F4 : Exit
keybd_event.Call(0x12, 1, 0, 0)
keybd_event.Call(0x73, 1, 0, 0)
keybd_event.Call(0x73, 1, 0X2, 0)
keybd_event.Call(0x12, 1, 0X2, 0)
sleep(1)
puts "截图保存的路径为:#{real_file_path}"
return true
else
puts "保存的文件扩展名不正确,路径必须带文件名且文件扩展名必须为.jpg或.bmp"
return false
end
end # def ScreenCapture end
end #class ScreenClass end
调用方法如下:
require 'LibScreen.rb'
#初始对象
ScreenClass = ScreenClass.new
#截取整个屏幕
ScreenClass.ScreenCapture("c:\\test1.jpg")
#截取当前激活的窗口
ScreenClass.ScreenCapture("c:\\test2.jpg",true) |
|