51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 5085|回复: 3
打印 上一主题 下一主题

Watir 学习系列--windows下截图

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2010-6-4 12:57:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用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)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
发表于 2010-7-7 15:48:35 | 只看该作者

回复 1# 的帖子

顶,真的不错,帮了我大忙
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2011-10-11 12:17:55 | 只看该作者
请问下, 这个方法在最新的watir上怎么不适用呢??

有更好的吗》?
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2011-10-12 10:06:18 | 只看该作者
回复 4# 山东白水泉


    watir有自带的截图方法,你可以去源码里面看看,screen_capture.rb
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-5-2 11:29 , Processed in 0.079082 second(s), 26 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表