2009-09-11 8 views
3

Je cherche un moyen de passer mes pages Web via un validateur DTD dans le cadre de mes tests WatiN, mais je n'ai pas encore trouvé un moyen clair d'accéder au HTML brut. Y a-t-il un moyen intégré de le faire?Accéder à la source de la page complète dans WatiN

Je pense que je pourrais accéder à la propriété IE.InternetExplorer et QueryInterface pour l'interface IPersistStreamInit et sérialiser le document à un IStream, mais il semble que beaucoup de travail pour ce que je suppose que doit être une tâche assez commune.

Ai-je quelque chose d'évident dans WatiN? Ou quelqu'un peut-il penser à une meilleure solution que celle que j'ai décrite ci-dessus? Cette solution est très spécifique à IE après tout.

Répondre

0

Il ne semble pas y avoir de meilleur moyen. J'ai déposé un feature request et j'ai soumis un patch au trackfor sourceforge de WatiN.

1

Voici comment vous accédez au code source:

browser.ActiveElement.Parent.OuterHtml 
+0

Merci, mais si je me souviens bien OuterHtml renvoie le code HTML comme il semble après avoir été modifié par IE. Ma conjecture est que IE interprète le HTML et construit un DOM. Lorsque vous accédez à OuterHtml IE sérialise le DOM au format texte et cela est légèrement différent de l'original. Je veux une copie textuelle du code HTML afin que je puisse exécuter la validation dessus. –

0

Pensée de laisser tomber quelques lignes pour aider tous ceux qui luttent là-bas pour obtenir la source vierge HTML d'une page Web via Watin sans toutefois rapiéçage Watin - juste pour le goût. Donc, en capitalisant sur le patch de Johan Levin, j'ai assemblé ce qui suit. Sois en sécurité et espère que tu le trouveras utile.

private static TextVariant GetWebPageSource(IE browser) 
    { 
    IHTMLDocument2 htmlDocument = ((IEDocument)(browser.DomContainer.NativeDocument)).HtmlDocument; 
    Encoding encoding = Encoding.GetEncoding(htmlDocument.charset); 
     IPersistStreamInit persistStream = (IPersistStreamInit)htmlDocument; 
     MinimalIStream stream = new MinimalIStream(); 
     persistStream.Save(stream, false); 
     return new TextVariant(encoding.GetString(stream.ToArray())); 
    } 

    [Guid("7FD52380-4E07-101B-AE2D-08002B2EC713")] 
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IPersistStreamInit 
    { 
     void GetClassID(out Guid pClassID); 
     int IsDirty(); 
     void Load(IStream pStm); 
     void Save(IStream pStm, bool fClearDirty); 
     void GetSizeMax(out long pcbSize); 
     void InitNew(); 
    } 

    // http://stackoverflow.com/questions/6601355/passing-an-fstream-or-equivalent-from-c-to-c-through-cli 
    [ClassInterface(ClassInterfaceType.AutoDispatch)] 
    public class MinimalIStream : MemoryStream, IStream 
    { 
     public MinimalIStream() { } 

     public MinimalIStream(byte[] data) : base(data) { } 

     #region IStream Members 
     public void Write(byte[] pv, int cb, IntPtr pcbWritten) 
     { 
      base.Write(pv, 0, cb); 
      if (pcbWritten != IntPtr.Zero) 
       Marshal.WriteInt64(pcbWritten, (long)cb); 
     } 

     public void Stat(out STATSTG pstatstg, int grfStatFlag) 
     { 
      pstatstg = new STATSTG(); 
      pstatstg.cbSize = base.Length; 
     } 

     public void Read(byte[] pv, int cb, IntPtr pcbRead) 
     { 
      long bytes_read = base.Read(pv, 0, cb); 
      if (pcbRead != IntPtr.Zero) Marshal.WriteInt64(pcbRead, bytes_read); 
     } 

     public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) 
     { 
      long pos = base.Seek(dlibMove, (SeekOrigin)dwOrigin); 
      if (plibNewPosition != IntPtr.Zero) Marshal.WriteInt64(plibNewPosition, pos); 
     } 

     public void Clone(out IStream ppstm) 
     { 
      ppstm = null; 
     } 

     public void Commit(int grfCommitFlags) 
     { 
     } 

     public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) 
     { 
     } 

     public void LockRegion(long libOffset, long cb, int dwLockType) 
     { 
     } 

     public void SetSize(long libNewSize) 
     { 
     } 

     public void Revert() 
     { 
     } 

     public void UnlockRegion(long libOffset, long cb, int dwLockType) 
     { 
     } 
     #endregion 
    } 
+0

Qu'est-ce que "TextVariant"? – deerchao

+0

Ne fonctionne pas. Semble prendre seulement le début mais pas toutes les sources. – deerchao

+0

Ajouter le code ci-dessous avant d'appeler GetWebPageSource() pour obtenir le texte complet: – deerchao

0

Je trouve:

browser.ActiveElement.Parent.OuterHtml 

ne sera pas toujours obtenir tout, comme dépend de votre 'activeElement', donc:

browser.Body.Parent.OuterHtml 

semble mieux fonctionner. (browser étant votre instance de IE)

Bien que je crois que Johan Levin a raison de dire que le DOM est sérialisé au format texte. Il ne serait donc pas plus simple de récupérer le document par son URL (sans utiliser WatiN) pour le valider.

1

chaîne html = navigateur.Body.Parent.OuterHtml;

Questions connexes