문제

인터넷 익스플로러 전용 웹 응용 프로그램이 있습니다.

테스트를 자동화하기 위해 우리가 할 수있는 일을 탐색하고 있습니다.

셀레늄은 좋은 도구처럼 보이지만 링크 등을 활성화 할 수 있어야합니다. 응용 프로그램은 이런 종류의 테스트를 염두에두고 구축되지 않았으므로 일반적으로 id 주요 요소의 속성.

아무 문제도 없다고 생각합니다. XPath 표현식을 사용할 수 있다고 생각합니다. 그러나 버튼에 대한 올바른 xpath를 찾는 것은 페이지 소스를 검사하여 수행하면 왕의 고통입니다.

Firefox / FireBug를 사용하면 요소를 선택한 다음 "Copy XPath"를 사용하여 표현식을 얻을 수 있습니다.

IE 개발자 도구 모음이 있고 실망스럽게 가깝습니다. 관심있는 요소를 선택하고 이에 대한 모든 종류의 정보를 표시하려면 클릭 할 수 있습니다. 그러나 나는 그것에 대한 xpath를 결정하는 편리한 방법을 볼 수 없습니다.

그렇다면 IE와 함께이 작업을 수행하는 방법이 있습니까?

도움이 되었습니까?

해결책

나는 책갈피를 사용할 것입니다. 나는 하나의 XPath 관련이 있지만 IE에서 작동하는지 모르겠습니다. 가야하지만 테스트하고 IE에서 작동하면 줄 것입니다.

내 책갈피에서 웹 개발자를위한 두 개의 북마크 사이트 : Subsimple의 책갈피 그리고 Squarefree의 책갈피. 거기에 많은 유용한 것들 ...

편집] 좋아요, 돌아 왔어요. 내가 가진 북마크는 FF만을위한 것이었고 최적이 아니었다. 원래 아이디어의 아이디어를 사용하더라도 마침내 다시 작성했습니다. 내가 찾은 곳을 찾을 수 없습니다.

확장 JS :

function getNode(node)
{
  var nodeExpr = node.tagName;
  if (nodeExpr == null)  // Eg. node = #text
    return null;
  if (node.id != '')
  {
    nodeExpr += "[@id='" + node.id + "']";
    // We don't really need to go back up to //HTML, since IDs are supposed
    // to be unique, so they are a good starting point.
    return "/" + nodeExpr;
  }
// We don't really need this
//~   if (node.className != '')
//~   {
//~     nodeExpr += "[@class='" + node.className + "']";
//~   }
  // Find rank of node among its type in the parent
  var rank = 1;
  var ps = node.previousSibling;
  while (ps != null)
  {
    if (ps.tagName == node.tagName)
    {
      rank++;
    }
    ps = ps.previousSibling;
  }
  if (rank > 1)
  {
    nodeExpr += '[' + rank + ']';
  }
  else
  {
    // First node of its kind at this level. Are there any others?
    var ns = node.nextSibling;
    while (ns != null)
    {
      if (ns.tagName == node.tagName)
      {
        // Yes, mark it as being the first one
        nodeExpr += '[1]';
        break;
      }
      ns = ns.nextSibling;
    }
  }
  return nodeExpr;
}

var currentNode;
// Standard (?)
if (window.getSelection != undefined) 
  currentNode = window.getSelection().anchorNode;
// IE (if no selection, that's BODY)
else 
  currentNode = document.selection.createRange().parentElement();
if (currentNode == null)
{
  alert("No selection");
  return;
}
var path = [];
// Walk up the Dom
while (currentNode != undefined)
{
  var pe = getNode(currentNode);
  if (pe != null)
  {
    path.push(pe);
    if (pe.indexOf('@id') != -1)
      break;  // Found an ID, no need to go upper, absolute path is OK
  }
  currentNode = currentNode.parentNode;
}
var xpath = "/" + path.reverse().join('/');
alert(xpath);
// Copy to clipboard
// IE
if (window.clipboardData) clipboardData.setData("Text", xpath);
// FF's code to handle clipboard is much more complex 
// and might need to change prefs to allow changing the clipboard content.
// I omit it here as it isn't part of the original request.

요소를 선택하고 XPATH를 얻으려면 책갈피를 활성화해야합니다.

이제 북마크 버전 (감사합니다 북마크 빌더):


(IE는 매우 긴 북마크를 좋아하지 않기 때문에 두 부분으로 나누어야했습니다 (IE 버전에 따라 최대 크기는 다양합니다!). 첫 번째 (기능 DEF)를 활성화 한 다음 두 번째는 IE6으로 테스트해야합니다. )

javascript:function getNode(node){var nodeExpr=node.tagName;if(!nodeExpr)return null;if(node.id!=''){nodeExpr+="[@id='"+node.id+"']";return "/"+nodeExpr;}var rank=1;var ps=node.previousSibling;while(ps){if(ps.tagName==node.tagName){rank++;}ps=ps.previousSibling;}if(rank>1){nodeExpr+='['+rank+']';}else{var ns=node.nextSibling;while(ns){if(ns.tagName==node.tagName){nodeExpr+='[1]';break;}ns=ns.nextSibling;}}return nodeExpr;}
javascript:function o__o(){var currentNode=document.selection.createRange().parentElement();var path=[];while(currentNode){var pe=getNode(currentNode);if(pe){path.push(pe);if(pe.indexOf('@id')!=-1)break;}currentNode=currentNode.parentNode;}var xpath="/"+path.reverse().join('/');clipboardData.setData("Text", xpath);}o__o();

FF

javascript:function o__o(){function getNode(node){var nodeExpr=node.tagName;if(nodeExpr==null)return null;if(node.id!=''){nodeExpr+="[@id='"+node.id+"']";return "/"+nodeExpr;}var rank=1;var ps=node.previousSibling;while(ps!=null){if(ps.tagName==node.tagName){rank++;}ps=ps.previousSibling;}if(rank>1){nodeExpr+='['+rank+']';}else{var ns=node.nextSibling;while(ns!=null){if(ns.tagName==node.tagName){nodeExpr+='[1]';break;}ns=ns.nextSibling;}}return nodeExpr;}var currentNode=window.getSelection().anchorNode;if(currentNode==null){alert("No selection");return;}var path=[];while(currentNode!=undefined){var pe=getNode(currentNode);if(pe!=null){path.push(pe);if(pe.indexOf('@id')!=-1)break;}currentNode=currentNode.parentNode;}var xpath="/"+path.reverse().join('/');alert(xpath);}o__o();

다른 팁

북마크를 사용하여 Paul을 당황하게하기 때문에 나는 그들의 사용에 대해 약간의 소개를 추가해야합니다. 나는 물건을 섞지 않기 위해 별도의 메시지로 그것을한다.

북마크 (Favlets)는 브라우저의 주소 막대 (다른 URL과 같은)에 붙여 넣어 현재 페이지에서 실행되도록 설계된 작은 JavaScript 스크립트 (SIC)입니다.
실행 한 후 (붙여 넣기, Enter를 누르면) 재사용을 위해 북마크 할 수 있습니다 (IE의 즐겨 찾기에 추가). 브라우저는 대신 원래 URL을 북마크 할 수 있으며 북마크를 편집하고 URL을 스크립트로 바꾸어야합니다.
물론 빠른 액세스를 위해 URL 막대에 추가 할 수 있습니다.

이 스크립트는 현재 페이지의 일부인 것처럼 작용하여 글로벌 JS 변수 및 기능, DOM 객체 등에 액세스하는 것과 같습니다.
그것들은 정상처럼 매우 간단 할 수 있습니다 javascript: alert("Hello world!"); 또는 위의 것과 같이 상당히 복잡합니다. 값을 반환하는 경우 (또는 마지막 표현식에 값이있는 경우) 값은 현재 페이지를 대체합니다. 이를 피하기 위해 스크립트를 완료 할 수 있습니다. alert (결과를 표시하려면) 함수 정의에서 스크립트를 랩핑하고 위에서했던 것처럼이 기능을 호출하십시오. (일부는 또한 무효 (0)을 넣었습니다. 결국에는 나쁜 연습으로 보이는 것을 보았습니다.)

기능 솔루션은 스크립트의 모든 변수를 애플릿에 로컬로 만드는 장점이 있습니다 (선언 된 경우 var, 물론), 로컬 페이지에 스크립트가있는 간섭/부작용을 피하십시오. 그렇기 때문에 랩핑 함수가 로컬 스크립트와 충돌 할 가능성이없는 이름이 있어야합니다.

일부 브라우저 (읽기 : "IE")는 인식의 크기 인 Max를 제한 할 수 있습니다. 버전에 따라 다양한 길이 (감소하는 경향). 그렇기 때문에 모든 쓸모없는 공백이 제거되는 이유 (위의 링크 된 서점 빌더는 그에 적합합니다). 또한 Favlet을 두 개로 분할해야했습니다. 첫 번째 부분은 기능을 정의합니다 (페이지가 변경/새로 고침되지 않는 한 살아) 두 번째 부분은 그것을 사용했습니다.

유용한 도구, 특히 사용자 스크립트를 허용하지 않는 브라우저 (à la greasemonkey) 또는이 확장 기능이없는 도구.

책갈피 코드를 C#에 다시 작성 했으므로 유용하다면 사용하십시오. 사용하십시오 ;-)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Anotation.Toolbar
{
    class XPath
    {
        public static string getXPath(mshtml.IHTMLElement element)
        {
            if (element == null)
                return "";
            mshtml.IHTMLElement currentNode = element;
            ArrayList path = new ArrayList();

            while (currentNode != null)
            {
                string pe = getNode(currentNode);
                if (pe != null)
                {
                    path.Add(pe);
                    if (pe.IndexOf("@id") != -1)
                        break;  // Found an ID, no need to go upper, absolute path is OK
                }
                currentNode = currentNode.parentElement;
            }
            path.Reverse();
            return join(path, "/");
        }

        private static string join(ArrayList items, string delimiter)
        {
          StringBuilder sb = new StringBuilder();
          foreach (object item in items)
          {
            if (item == null)
                continue;

            sb.Append(delimiter);
            sb.Append(item);
          }
          return sb.ToString();
        }

        private static string getNode(mshtml.IHTMLElement node)
        {
            string nodeExpr = node.tagName;
            if (nodeExpr == null)  // Eg. node = #text
                return null;
            if (node.id != "" && node.id != null)
            {
                nodeExpr += "[@id='" + node.id + "']";
                // We don't really need to go back up to //HTML, since IDs are supposed
                // to be unique, so they are a good starting point.
                return "/" + nodeExpr;
            }

            // Find rank of node among its type in the parent
            int rank = 1;
            mshtml.IHTMLDOMNode nodeDom = node as mshtml.IHTMLDOMNode;
            mshtml.IHTMLDOMNode psDom = nodeDom.previousSibling;
            mshtml.IHTMLElement ps = psDom as mshtml.IHTMLElement;
            while (ps != null)
            {
                if (ps.tagName == node.tagName)
                {
                    rank++;
                }
                psDom = psDom.previousSibling;
                ps = psDom as mshtml.IHTMLElement;
            }
            if (rank > 1)
            {
                nodeExpr += "[" + rank + "]";
            }
            else
            { // First node of its kind at this level. Are there any others?
                mshtml.IHTMLDOMNode nsDom = nodeDom.nextSibling;
                mshtml.IHTMLElement ns = nsDom as mshtml.IHTMLElement;
                while (ns != null)
                {
                    if (ns.tagName == node.tagName)
                    { // Yes, mark it as being the first one
                        nodeExpr += "[1]";
                        break;
                    }
                    nsDom = nsDom.nextSibling;
                    ns = nsDom as mshtml.IHTMLElement;
                }
            }
            return nodeExpr;
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top