wbemprox: Return an empty object if the path is NULL or empty.
[wine] / dlls / mshtml / tests / dom.c
1 /*
2  * Copyright 2007-2011 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "mshtmcid.h"
31 #include "mshtmhst.h"
32 #include "docobj.h"
33 #include "dispex.h"
34 #include "mshtml_test.h"
35 #include "objsafe.h"
36 #include "htiface.h"
37 #include "tlogstg.h"
38
39 static INT (WINAPI *pLCIDToLocaleName)(LCID,LPWSTR,INT,DWORD);
40 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void);
41
42 static const char doc_blank[] = "<html></html>";
43 static const char doc_str1[] = "<html><body>test</body></html>";
44 static const char range_test_str[] =
45     "<html><body>test \na<font size=\"2\">bc\t123<br /> it's\r\n  \t</font>text<br /></body></html>";
46 static const char range_test2_str[] =
47     "<html><body>abc<hr />123<br /><hr />def</body></html>";
48 static const char elem_test_str[] =
49     "<html><head><title>test</title><style id=\"styleid\">.body { margin-right: 0px; }</style>"
50     "<meta id=\"metaid\" name=\"meta name\" http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
51     "<link id=\"linkid\"></head>"
52     "<body onload=\"Testing()\">text test<!-- a comment -->"
53     "<a id=\"a\" href=\"http://test\" name=\"x\">link</a>"
54     "<input id=\"in\" class=\"testclass\" tabIndex=\"2\" title=\"test title\" />"
55     "<select id=\"s\"><option id=\"x\" value=\"val1\">opt1</option><option id=\"y\">opt2</option></select>"
56     "<textarea id=\"X\">text text</textarea>"
57     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td>td1 text</td><td>td2 text</td></tr></tbody></table>"
58     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
59     "<test /><object id=\"objid\" name=\"objname\" vspace=100></object><embed />"
60     "<img id=\"imgid\" name=\"WineImg\"/>"
61     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
62     "<form id=\"frm\"></form>"
63     "<div id=\"attr\" attr1=\"attr1\" attr2 attr3=\"attr3\"></div>"
64     "</body></html>";
65 static const char elem_test2_str[] =
66     "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
67     "<link id=\"linkid\" rel=\"stylesheet\" href=\"about:blank\" type=\"text/css\"></head>"
68     "<body><div id=\"divid\" emptyattr=\"\" onclick=\"parseInt();\"></div></body>"
69     "</html>";
70
71 static const char indent_test_str[] =
72     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
73 static const char cond_comment_str[] =
74     "<html><head><title>test</title></head><body>"
75     "<!--[if gte IE 4]> <br> <![endif]-->"
76     "</body></html>";
77 static const char frameset_str[] =
78     "<html><head><title>frameset test</title></head><frameset rows=\"25, 25, *\">"
79     "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
80     "<frame src=\"about:blank\" id=\"fr3\">"
81     "</frameset></html>";
82 static const char emptydiv_str[] =
83     "<html><head><title>emptydiv test</title></head>"
84     "<body><div id=\"divid\"></div></body></html>";
85 static const char noscript_str[] =
86     "<html><head><title>noscript test</title><noscript><style>.body { margin-right: 0px; }</style></noscript></head>"
87     "<body><noscript><div>test</div></noscript></body></html>";
88 static const char doctype_str[] =
89     "<!DOCTYPE html>"
90     "<html><head><title>emptydiv test</title></head>"
91     "<body><div id=\"divid\"></div></body></html>";
92
93 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
94 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
95 static WCHAR wordW[] = {'w','o','r','d',0};
96
97 typedef enum {
98     ET_NONE,
99     ET_HTML,
100     ET_HEAD,
101     ET_TITLE,
102     ET_BODY,
103     ET_A,
104     ET_INPUT,
105     ET_SELECT,
106     ET_TEXTAREA,
107     ET_OPTION,
108     ET_STYLE,
109     ET_BLOCKQUOTE,
110     ET_P,
111     ET_BR,
112     ET_TABLE,
113     ET_TBODY,
114     ET_SCRIPT,
115     ET_TEST,
116     ET_TESTG,
117     ET_COMMENT,
118     ET_IMG,
119     ET_TR,
120     ET_TD,
121     ET_IFRAME,
122     ET_FORM,
123     ET_FRAME,
124     ET_OBJECT,
125     ET_EMBED,
126     ET_DIV,
127     ET_META,
128     ET_NOSCRIPT,
129     ET_LINK
130 } elem_type_t;
131
132 static const IID * const none_iids[] = {
133     &IID_IUnknown,
134     NULL
135 };
136
137 static const IID * const doc_node_iids[] = {
138     &IID_IHTMLDOMNode,
139     &IID_IHTMLDOMNode2,
140     &IID_IHTMLDocument,
141     &IID_IHTMLDocument2,
142     &IID_IHTMLDocument3,
143     &IID_IHTMLDocument4,
144     &IID_IHTMLDocument5,
145     &IID_IDispatchEx,
146     &IID_IConnectionPointContainer,
147     &IID_IInternetHostSecurityManager,
148     &IID_IOleContainer,
149     &IID_IObjectSafety,
150     &IID_IProvideClassInfo,
151     NULL
152 };
153
154 static const IID * const doc_obj_iids[] = {
155     &IID_IHTMLDocument,
156     &IID_IHTMLDocument2,
157     &IID_IHTMLDocument3,
158     &IID_IHTMLDocument4,
159     &IID_IHTMLDocument5,
160     &IID_IDispatchEx,
161     &IID_IConnectionPointContainer,
162     &IID_ICustomDoc,
163     &IID_IOleContainer,
164     &IID_IObjectSafety,
165     &IID_IProvideClassInfo,
166     &IID_ITargetContainer,
167     NULL
168 };
169
170 #define ELEM_IFACES \
171     &IID_IHTMLDOMNode,  \
172     &IID_IHTMLDOMNode2, \
173     &IID_IHTMLElement,  \
174     &IID_IHTMLElement2, \
175     &IID_IHTMLElement3, \
176     &IID_IHTMLElement4, \
177     &IID_IDispatchEx
178
179 static const IID * const elem_iids[] = {
180     ELEM_IFACES,
181     &IID_IConnectionPointContainer,
182     NULL
183 };
184
185 static const IID * const body_iids[] = {
186     ELEM_IFACES,
187     &IID_IHTMLTextContainer,
188     &IID_IHTMLBodyElement,
189     &IID_IConnectionPointContainer,
190     NULL
191 };
192
193 static const IID * const anchor_iids[] = {
194     ELEM_IFACES,
195     &IID_IHTMLAnchorElement,
196     &IID_IConnectionPointContainer,
197     NULL
198 };
199
200 static const IID * const input_iids[] = {
201     ELEM_IFACES,
202     &IID_IHTMLInputElement,
203     &IID_IHTMLInputTextElement,
204     &IID_IConnectionPointContainer,
205     NULL
206 };
207
208 static const IID * const select_iids[] = {
209     ELEM_IFACES,
210     &IID_IHTMLSelectElement,
211     &IID_IConnectionPointContainer,
212     NULL
213 };
214
215 static const IID * const textarea_iids[] = {
216     ELEM_IFACES,
217     &IID_IHTMLTextAreaElement,
218     &IID_IConnectionPointContainer,
219     NULL
220 };
221
222 static const IID * const option_iids[] = {
223     ELEM_IFACES,
224     &IID_IHTMLOptionElement,
225     &IID_IConnectionPointContainer,
226     NULL
227 };
228
229 static const IID * const table_iids[] = {
230     ELEM_IFACES,
231     &IID_IHTMLTable,
232     &IID_IHTMLTable2,
233     &IID_IHTMLTable3,
234     &IID_IConnectionPointContainer,
235     NULL
236 };
237
238 static const IID * const script_iids[] = {
239     ELEM_IFACES,
240     &IID_IHTMLScriptElement,
241     &IID_IConnectionPointContainer,
242     NULL
243 };
244
245 static const IID * const text_iids[] = {
246     &IID_IHTMLDOMNode,
247     &IID_IHTMLDOMNode2,
248     &IID_IHTMLDOMTextNode,
249     NULL
250 };
251
252 static const IID * const attr_iids[] = {
253     &IID_IHTMLDOMAttribute,
254     &IID_IDispatchEx,
255     NULL
256 };
257
258 static const IID * const location_iids[] = {
259     &IID_IDispatch,
260     &IID_IHTMLLocation,
261     NULL
262 };
263
264 static const IID * const window_iids[] = {
265     &IID_IDispatch,
266     &IID_IHTMLWindow2,
267     &IID_IHTMLWindow3,
268     &IID_IDispatchEx,
269     &IID_IServiceProvider,
270     NULL
271 };
272
273 static const IID * const comment_iids[] = {
274     ELEM_IFACES,
275     &IID_IHTMLCommentElement,
276     &IID_IConnectionPointContainer,
277     NULL
278 };
279
280 static const IID * const img_iids[] = {
281     ELEM_IFACES,
282     &IID_IHTMLImgElement,
283     &IID_IConnectionPointContainer,
284     NULL
285 };
286
287 static const IID * const tr_iids[] = {
288     ELEM_IFACES,
289     &IID_IHTMLTableRow,
290     &IID_IConnectionPointContainer,
291     NULL
292 };
293
294 static const IID * const td_iids[] = {
295     ELEM_IFACES,
296     &IID_IHTMLTableCell,
297     &IID_IConnectionPointContainer,
298     NULL
299 };
300
301 static const IID * const frame_iids[] = {
302     ELEM_IFACES,
303     &IID_IHTMLFrameBase,
304     &IID_IHTMLFrameBase2,
305     &IID_IConnectionPointContainer,
306     NULL
307 };
308
309 static const IID * const head_iids[] = {
310     ELEM_IFACES,
311     &IID_IHTMLHeadElement,
312     &IID_IConnectionPointContainer,
313     NULL
314 };
315
316 static const IID * const title_iids[] = {
317     ELEM_IFACES,
318     &IID_IHTMLTitleElement,
319     &IID_IConnectionPointContainer,
320     NULL
321 };
322
323 static const IID * const meta_iids[] = {
324     ELEM_IFACES,
325     &IID_IHTMLMetaElement,
326     &IID_IConnectionPointContainer,
327     NULL
328 };
329
330 static const IID * const link_iids[] = {
331     ELEM_IFACES,
332     &IID_IHTMLLinkElement,
333     &IID_IConnectionPointContainer,
334     NULL
335 };
336
337 static const IID * const object_iids[] = {
338     ELEM_IFACES,
339     &IID_IHTMLObjectElement,
340     &IID_IHTMLObjectElement2,
341     /* FIXME: No IConnectionPointContainer */
342     NULL
343 };
344
345 static const IID * const embed_iids[] = {
346     ELEM_IFACES,
347     &IID_IHTMLEmbedElement,
348     /* FIXME: No IConnectionPointContainer */
349     NULL
350 };
351
352 static const IID * const iframe_iids[] = {
353     ELEM_IFACES,
354     &IID_IHTMLFrameBase,
355     &IID_IHTMLFrameBase2,
356     &IID_IHTMLIFrameElement,
357     &IID_IHTMLIFrameElement2,
358     &IID_IConnectionPointContainer,
359     NULL
360 };
361
362 static const IID * const form_iids[] = {
363     ELEM_IFACES,
364     &IID_IHTMLFormElement,
365     &IID_IConnectionPointContainer,
366     NULL
367 };
368
369 static const IID * const styleelem_iids[] = {
370     ELEM_IFACES,
371     &IID_IHTMLStyleElement,
372     &IID_IConnectionPointContainer,
373     NULL
374 };
375
376 static const IID * const generic_iids[] = {
377     ELEM_IFACES,
378     &IID_IHTMLGenericElement,
379     &IID_IConnectionPointContainer,
380     NULL
381 };
382
383 static const IID * const style_iids[] = {
384     &IID_IUnknown,
385     &IID_IDispatch,
386     &IID_IDispatchEx,
387     &IID_IHTMLStyle,
388     &IID_IHTMLStyle2,
389     &IID_IHTMLStyle3,
390     &IID_IHTMLStyle4,
391     NULL
392 };
393
394 static const IID * const cstyle_iids[] = {
395     &IID_IUnknown,
396     &IID_IDispatch,
397     &IID_IDispatchEx,
398     &IID_IHTMLCurrentStyle,
399     &IID_IHTMLCurrentStyle2,
400     &IID_IHTMLCurrentStyle3,
401     NULL
402 };
403
404 static const IID * const img_factory_iids[] = {
405     &IID_IUnknown,
406     &IID_IDispatch,
407     &IID_IDispatchEx,
408     &IID_IHTMLImageElementFactory,
409     NULL
410 };
411
412 typedef struct {
413     const char *tag;
414     REFIID *iids;
415     const IID *dispiid;
416 } elem_type_info_t;
417
418 static const elem_type_info_t elem_type_infos[] = {
419     {"",          none_iids,        NULL},
420     {"HTML",      elem_iids,        NULL},
421     {"HEAD",      head_iids,        &DIID_DispHTMLHeadElement},
422     {"TITLE",     title_iids,       &DIID_DispHTMLTitleElement},
423     {"BODY",      body_iids,        &DIID_DispHTMLBody},
424     {"A",         anchor_iids,      &DIID_DispHTMLAnchorElement},
425     {"INPUT",     input_iids,       &DIID_DispHTMLInputElement},
426     {"SELECT",    select_iids,      &DIID_DispHTMLSelectElement},
427     {"TEXTAREA",  textarea_iids,    &DIID_DispHTMLTextAreaElement},
428     {"OPTION",    option_iids,      &DIID_DispHTMLOptionElement},
429     {"STYLE",     styleelem_iids,   &DIID_DispHTMLStyleElement},
430     {"BLOCKQUOTE",elem_iids,        NULL},
431     {"P",         elem_iids,        NULL},
432     {"BR",        elem_iids,        NULL},
433     {"TABLE",     table_iids,       &DIID_DispHTMLTable},
434     {"TBODY",     elem_iids,        NULL},
435     {"SCRIPT",    script_iids,      &DIID_DispHTMLScriptElement},
436     {"TEST",      elem_iids,        &DIID_DispHTMLUnknownElement},
437     {"TEST",      generic_iids,     &DIID_DispHTMLGenericElement},
438     {"!",         comment_iids,     &DIID_DispHTMLCommentElement},
439     {"IMG",       img_iids,         &DIID_DispHTMLImg},
440     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
441     {"TD",        td_iids,          &DIID_DispHTMLTableCell},
442     {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame},
443     {"FORM",      form_iids,        &DIID_DispHTMLFormElement},
444     {"FRAME",     frame_iids,       &DIID_DispHTMLFrameElement},
445     {"OBJECT",    object_iids,      &DIID_DispHTMLObjectElement},
446     {"EMBED",     embed_iids,       &DIID_DispHTMLEmbed},
447     {"DIV",       elem_iids,        NULL},
448     {"META",      meta_iids,        &DIID_DispHTMLMetaElement},
449     {"NOSCRIPT",  elem_iids,        NULL /*&DIID_DispHTMLNoShowElement*/},
450     {"LINK",      link_iids,        &DIID_DispHTMLLinkElement}
451 };
452
453 static const char *dbgstr_guid(REFIID riid)
454 {
455     static char buf[50];
456
457     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
458             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
459             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
460             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
461
462     return buf;
463 }
464
465 static int strcmp_wa(LPCWSTR strw, const char *stra)
466 {
467     CHAR buf[512];
468     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
469     return lstrcmpA(stra, buf);
470 }
471
472 static BSTR a2bstr(const char *str)
473 {
474     BSTR ret;
475     int len;
476
477     if(!str)
478         return NULL;
479
480     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
481     ret = SysAllocStringLen(NULL, len);
482     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
483
484     return ret;
485 }
486
487 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
488 {
489     IUnknown *unk1, *unk2;
490
491     if(iface1 == iface2)
492         return TRUE;
493
494     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
495     IUnknown_Release(unk1);
496     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
497     IUnknown_Release(unk2);
498
499     return unk1 == unk2;
500 }
501
502 static IHTMLDocument2 *create_document(void)
503 {
504     IHTMLDocument2 *doc;
505     IHTMLDocument5 *doc5;
506     HRESULT hres;
507
508     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
509             &IID_IHTMLDocument2, (void**)&doc);
510     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
511     if(FAILED(hres))
512         return NULL;
513
514     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
515     if(FAILED(hres)) {
516         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
517         IHTMLDocument2_Release(doc);
518         return NULL;
519     }
520
521     IHTMLDocument5_Release(doc5);
522     return doc;
523 }
524
525 #define get_dispex_iface(u) _get_dispex_iface(__LINE__,u)
526 static IDispatchEx *_get_dispex_iface(unsigned line, IUnknown *unk)
527 {
528     IDispatchEx *dispex;
529     HRESULT hres;
530
531     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
532     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
533     return dispex;
534 }
535
536 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
537 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
538 {
539     const IID * const *piid;
540     IUnknown *unk;
541     HRESULT hres;
542
543      for(piid = iids; *piid; piid++) {
544         hres = IUnknown_QueryInterface(iface, *piid, (void**)&unk);
545         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", dbgstr_guid(*piid), hres);
546         if(SUCCEEDED(hres))
547             IUnknown_Release(unk);
548     }
549 }
550
551 #define test_no_iface(a,b) _test_no_iface(__LINE__,a,b)
552 static void _test_no_iface(unsigned line, IUnknown *iface, REFIID iid)
553 {
554     IUnknown *unk;
555     HRESULT hres;
556
557     unk = (void*)0xdeadbeef;
558     hres = IUnknown_QueryInterface(iface, iid, (void**)&unk);
559     ok_(__FILE__,line)(hres == E_NOINTERFACE, "hres = %08x, expected E_NOINTERFACE\n", hres);
560     ok_(__FILE__,line)(!unk, "unk = %p\n", unk);
561 }
562
563 #define test_get_dispid(u,id) _test_get_dispid(__LINE__,u,id)
564 static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
565 {
566     IDispatchEx *dispex = _get_dispex_iface(line, unk);
567     ITypeInfo *typeinfo;
568     BOOL ret = FALSE;
569     UINT ticnt;
570     HRESULT hres;
571
572     ticnt = 0xdeadbeef;
573     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
574     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
575     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
576
577     hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
578     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
579
580     if(SUCCEEDED(hres)) {
581         TYPEATTR *type_attr;
582
583         hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
584         ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
585         if(hres == S_OK) {
586             *iid = type_attr->guid;
587             ret = TRUE;
588         }
589
590         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
591         ITypeInfo_Release(typeinfo);
592     }
593
594     IDispatchEx_Release(dispex);
595     return ret;
596 }
597
598 #define test_disp_value(u) _test_disp_value(__LINE__,u,v)
599 static void _test_disp_value(unsigned line, IUnknown *unk, const char *val)
600 {
601     IDispatchEx *dispex = _get_dispex_iface(line, unk);
602     DISPPARAMS dp  = {NULL,NULL,0,0};
603     EXCEPINFO ei;
604     VARIANT var;
605     HRESULT hres;
606
607     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
608     IDispatchEx_Release(dispex);
609     ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres);
610
611     ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var));
612     ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val);
613     VariantClear(&var);
614 }
615
616 #define test_disp(u,id,v) _test_disp(__LINE__,u,id,v)
617 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val)
618 {
619     IID iid;
620
621     if(_test_get_dispid(line, unk, &iid))
622         ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", dbgstr_guid(&iid));
623
624     if(val)
625         _test_disp_value(line, unk, val);
626 }
627
628 #define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v)
629 static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val)
630 {
631     IID iid;
632
633     if(_test_get_dispid(line, unk, &iid))
634         ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)),
635                 "unexpected guid %s\n", dbgstr_guid(&iid));
636
637     if(val)
638         _test_disp_value(line, unk, val);
639 }
640
641 #define test_class_info(u) _test_class_info(__LINE__,u)
642 static void _test_class_info(unsigned line, IUnknown *unk)
643 {
644     IProvideClassInfo *classinfo;
645     ITypeInfo *typeinfo;
646     TYPEATTR *type_attr;
647     HRESULT hres;
648
649     hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo, (void**)&classinfo);
650     ok_(__FILE__,line)(hres == S_OK, "Could not get IProvideClassInfo interface: %08x\n", hres);
651     if(FAILED(hres))
652         return;
653
654     hres = IProvideClassInfo_GetClassInfo(classinfo, &typeinfo);
655     ok_(__FILE__,line)(hres == S_OK, "Could not get ITypeInfo interface: %08x\n", hres);
656     if(FAILED(hres))
657     {
658         IProvideClassInfo_Release(classinfo);
659         return;
660     }
661
662     hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
663     ok_(__FILE__,line)(hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
664     if(SUCCEEDED(hres))
665     {
666         ok_(__FILE__,line)(IsEqualGUID(&type_attr->guid, &CLSID_HTMLDocument),
667                 "unexpected guid %s\n", dbgstr_guid(&type_attr->guid));
668         ok_(__FILE__,line)(type_attr->typekind == TKIND_COCLASS,
669                 "unexpected typekind %d\n", type_attr->typekind);
670         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
671     }
672
673     ITypeInfo_Release(typeinfo);
674     IProvideClassInfo_Release(classinfo);
675 }
676
677 #define set_dispex_value(a,b,c) _set_dispex_value(__LINE__,a,b,c)
678 static void _set_dispex_value(unsigned line, IUnknown *unk, const char *name, VARIANT *val)
679 {
680     IDispatchEx *dispex = _get_dispex_iface(line, unk);
681     DISPPARAMS dp = {val, NULL, 1, 0};
682     EXCEPINFO ei;
683     DISPID id;
684     BSTR str;
685     HRESULT hres;
686
687     str = a2bstr(name);
688     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure|fdexNameCaseInsensitive, &id);
689     SysFreeString(str);
690     ok_(__FILE__,line)(hres == S_OK, "GetDispID failed: %08x\n", hres);
691
692     memset(&ei, 0, sizeof(ei));
693     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
694     ok_(__FILE__,line)(hres == S_OK, "InvokeEx failed: %08x\n", hres);
695
696 }
697
698 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
699 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
700 {
701     IHTMLElement *elem;
702     HRESULT hres;
703
704     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
705     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres);
706     return elem;
707 }
708
709 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
710 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
711 {
712     IHTMLElement2 *elem;
713     HRESULT hres;
714
715     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem);
716     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres);
717     return elem;
718 }
719
720 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
721 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
722 {
723     IHTMLElement3 *elem;
724     HRESULT hres;
725
726     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem);
727     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres);
728     return elem;
729 }
730
731 #define get_elem4_iface(u) _get_elem4_iface(__LINE__,u)
732 static IHTMLElement4 *_get_elem4_iface(unsigned line, IUnknown *unk)
733 {
734     IHTMLElement4 *elem;
735     HRESULT hres;
736
737     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement4, (void**)&elem);
738     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement4: %08x\n", hres);
739     return elem;
740 }
741
742 #define get_node_iface(u) _get_node_iface(__LINE__,u)
743 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
744 {
745     IHTMLDOMNode *node;
746     HRESULT hres;
747
748     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node);
749     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres);
750     return node;
751 }
752
753 #define get_node2_iface(u) _get_node2_iface(__LINE__,u)
754 static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk)
755 {
756     IHTMLDOMNode2 *node;
757     HRESULT hres;
758
759     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node);
760     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres);
761     return node;
762 }
763
764 #define get_img_iface(u) _get_img_iface(__LINE__,u)
765 static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk)
766 {
767     IHTMLImgElement *img;
768     HRESULT hres;
769
770     hres = IUnknown_QueryInterface(unk, &IID_IHTMLImgElement, (void**)&img);
771     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLImgElement: %08x\n", hres);
772     return img;
773 }
774
775 #define get_anchor_iface(u) _get_anchor_iface(__LINE__,u)
776 static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
777 {
778     IHTMLAnchorElement *anchor;
779     HRESULT hres;
780
781     hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor);
782     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres);
783     return anchor;
784 }
785
786 #define get_textarea_iface(u) _get_textarea_iface(__LINE__,u)
787 static IHTMLTextAreaElement *_get_textarea_iface(unsigned line, IUnknown *unk)
788 {
789     IHTMLTextAreaElement *textarea;
790     HRESULT hres;
791
792     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextAreaElement, (void**)&textarea);
793     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextAreaElement: %08x\n", hres);
794     return textarea;
795 }
796
797 #define get_select_iface(u) _get_select_iface(__LINE__,u)
798 static IHTMLSelectElement *_get_select_iface(unsigned line, IUnknown *unk)
799 {
800     IHTMLSelectElement *select;
801     HRESULT hres;
802
803     hres = IUnknown_QueryInterface(unk, &IID_IHTMLSelectElement, (void**)&select);
804     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLSelectElement: %08x\n", hres);
805     return select;
806 }
807
808 #define get_form_iface(u) _get_form_iface(__LINE__,u)
809 static IHTMLFormElement *_get_form_iface(unsigned line, IUnknown *unk)
810 {
811     IHTMLFormElement *form;
812     HRESULT hres;
813
814     hres = IUnknown_QueryInterface(unk, &IID_IHTMLFormElement, (void**)&form);
815     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLFormElement: %08x\n", hres);
816     return form;
817 }
818
819 #define get_text_iface(u) _get_text_iface(__LINE__,u)
820 static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk)
821 {
822     IHTMLDOMTextNode *text;
823     HRESULT hres;
824
825     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text);
826     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres);
827     return text;
828 }
829
830 #define get_comment_iface(u) _get_comment_iface(__LINE__,u)
831 static IHTMLCommentElement *_get_comment_iface(unsigned line, IUnknown *unk)
832 {
833     IHTMLCommentElement *comment;
834     HRESULT hres;
835
836     hres = IUnknown_QueryInterface(unk, &IID_IHTMLCommentElement, (void**)&comment);
837     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLCommentElement: %08x\n", hres);
838     return comment;
839 }
840
841 #define get_object_iface(u) _get_object_iface(__LINE__,u)
842 static IHTMLObjectElement *_get_object_iface(unsigned line, IUnknown *unk)
843 {
844     IHTMLObjectElement *obj;
845     HRESULT hres;
846
847     hres = IUnknown_QueryInterface(unk, &IID_IHTMLObjectElement, (void**)&obj);
848     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLObjectElement: %08x\n", hres);
849     return obj;
850 }
851
852 #define get_style_iface(u) _get_style_iface(__LINE__,u)
853 static IHTMLStyleElement *_get_style_iface(unsigned line, IUnknown *unk)
854 {
855     IHTMLStyleElement *obj;
856     HRESULT hres;
857
858     hres = IUnknown_QueryInterface(unk, &IID_IHTMLStyleElement, (void**)&obj);
859     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLStyleElement: %08x\n", hres);
860     return obj;
861 }
862
863 #define get_metaelem_iface(u) _get_metaelem_iface(__LINE__,u)
864 static IHTMLMetaElement *_get_metaelem_iface(unsigned line, IUnknown *unk)
865 {
866     IHTMLMetaElement *ret;
867     HRESULT hres;
868
869     hres = IUnknown_QueryInterface(unk, &IID_IHTMLMetaElement, (void**)&ret);
870     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLMetaElement: %08x\n", hres);
871     return ret;
872 }
873
874 #define get_link_iface(u) _get_link_iface(__LINE__,u)
875 static IHTMLLinkElement *_get_link_iface(unsigned line, IUnknown *unk)
876 {
877     IHTMLLinkElement *ret;
878     HRESULT hres;
879
880     hres = IUnknown_QueryInterface(unk, &IID_IHTMLLinkElement, (void**)&ret);
881     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLLinkElement: %08x\n", hres);
882     return ret;
883 }
884
885 #define get_iframe2_iface(u) _get_iframe2_iface(__LINE__,u)
886 static IHTMLIFrameElement2 *_get_iframe2_iface(unsigned line, IUnknown *unk)
887 {
888     IHTMLIFrameElement2 *ret;
889     HRESULT hres;
890
891     hres = IUnknown_QueryInterface(unk, &IID_IHTMLIFrameElement2, (void**)&ret);
892     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLIFrameElement: %08x\n", hres);
893     return ret;
894 }
895
896 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
897 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
898 {
899     IHTMLDOMNode *node = _get_node_iface(line, unk);
900     BSTR name;
901     HRESULT hres;
902
903     hres = IHTMLDOMNode_get_nodeName(node, &name);
904     IHTMLDOMNode_Release(node);
905     ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres);
906     ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname);
907
908     SysFreeString(name);
909 }
910
911 #define get_owner_doc(u) _get_owner_doc(__LINE__,u)
912 static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
913 {
914     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
915     IDispatch *disp = (void*)0xdeadbeef;
916     IHTMLDocument2 *doc = NULL;
917     HRESULT hres;
918
919     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
920     IHTMLDOMNode2_Release(node);
921     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
922
923     if(disp) {
924         hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
925         IDispatch_Release(disp);
926         ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
927     }
928
929     return doc;
930 }
931
932 #define get_doc_window(d) _get_doc_window(__LINE__,d)
933 static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
934 {
935     IHTMLWindow2 *window;
936     HRESULT hres;
937
938     window = NULL;
939     hres = IHTMLDocument2_get_parentWindow(doc, &window);
940     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
941     ok_(__FILE__,line)(window != NULL, "window == NULL\n");
942
943     return window;
944 }
945
946 #define clone_node(n,d) _clone_node(__LINE__,n,d)
947 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
948 {
949     IHTMLDOMNode *node = _get_node_iface(line, unk);
950     IHTMLDOMNode *ret = NULL;
951     HRESULT hres;
952
953     hres = IHTMLDOMNode_cloneNode(node, deep, &ret);
954     IHTMLDOMNode_Release(node);
955     ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres);
956     ok_(__FILE__,line)(ret != NULL, "ret == NULL\n");
957
958     return ret;
959
960 }
961
962 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
963 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
964 {
965     IHTMLElement *elem = _get_elem_iface(line, unk);
966     BSTR tag;
967     HRESULT hres;
968
969     hres = IHTMLElement_get_tagName(elem, &tag);
970     IHTMLElement_Release(elem);
971     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
972     ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
973
974     SysFreeString(tag);
975 }
976
977 #define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t)
978 static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type)
979 {
980     _test_elem_tag(line, unk, elem_type_infos[type].tag);
981     _test_ifaces(line, unk, elem_type_infos[type].iids);
982
983     if(elem_type_infos[type].dispiid && type != ET_A)
984         _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]");
985 }
986
987 #define get_node_type(n) _get_node_type(__LINE__,n)
988 static LONG _get_node_type(unsigned line, IUnknown *unk)
989 {
990     IHTMLDOMNode *node = _get_node_iface(line, unk);
991     LONG type = -1;
992     HRESULT hres;
993
994     hres = IHTMLDOMNode_get_nodeType(node, &type);
995     ok(hres == S_OK, "get_nodeType failed: %08x\n", hres);
996
997     IHTMLDOMNode_Release(node);
998
999     return type;
1000 }
1001
1002 #define get_child_nodes(u) _get_child_nodes(__LINE__,u)
1003 static IHTMLDOMChildrenCollection *_get_child_nodes(unsigned line, IUnknown *unk)
1004 {
1005     IHTMLDOMNode *node = _get_node_iface(line, unk);
1006     IHTMLDOMChildrenCollection *col = NULL;
1007     IDispatch *disp;
1008     HRESULT hres;
1009
1010     hres = IHTMLDOMNode_get_childNodes(node, &disp);
1011     IHTMLDOMNode_Release(node);
1012     ok_(__FILE__,line) (hres == S_OK, "get_childNodes failed: %08x\n", hres);
1013     if(FAILED(hres))
1014         return NULL;
1015
1016     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMChildrenCollection, (void**)&col);
1017     IDispatch_Release(disp);
1018     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMChildrenCollection: %08x\n", hres);
1019
1020     return col;
1021 }
1022
1023 #define get_child_item(c,i) _get_child_item(__LINE__,c,i)
1024 static IHTMLDOMNode *_get_child_item(unsigned line, IHTMLDOMChildrenCollection *col, LONG idx)
1025 {
1026     IHTMLDOMNode *node = NULL;
1027     IDispatch *disp;
1028     HRESULT hres;
1029
1030     hres = IHTMLDOMChildrenCollection_item(col, idx, &disp);
1031     ok(hres == S_OK, "item failed: %08x\n", hres);
1032
1033     node = _get_node_iface(line, (IUnknown*)disp);
1034     IDispatch_Release(disp);
1035
1036     return node;
1037 }
1038
1039 #define test_elem_attr(e,n,v) _test_elem_attr(__LINE__,e,n,v)
1040 static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, const char *exval)
1041 {
1042     VARIANT value;
1043     BSTR tmp;
1044     HRESULT hres;
1045
1046     VariantInit(&value);
1047
1048     tmp = a2bstr(name);
1049     hres = IHTMLElement_getAttribute(elem, tmp, 0, &value);
1050     SysFreeString(tmp);
1051     ok_(__FILE__,line) (hres == S_OK, "getAttribute failed: %08x\n", hres);
1052
1053     if(exval) {
1054         ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value));
1055         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value)));
1056     }else {
1057         ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value));
1058     }
1059
1060     VariantClear(&value);
1061 }
1062
1063 #define test_elem_offset(a,b) _test_elem_offset(__LINE__,a,b)
1064 static void _test_elem_offset(unsigned line, IUnknown *unk, const char *parent_tag)
1065 {
1066     IHTMLElement *elem = _get_elem_iface(line, unk);
1067     IHTMLElement *off_parent;
1068     LONG l;
1069     HRESULT hres;
1070
1071     hres = IHTMLElement_get_offsetTop(elem, &l);
1072     ok_(__FILE__,line) (hres == S_OK, "get_offsetTop failed: %08x\n", hres);
1073
1074     hres = IHTMLElement_get_offsetHeight(elem, &l);
1075     ok_(__FILE__,line) (hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
1076
1077     hres = IHTMLElement_get_offsetWidth(elem, &l);
1078     ok_(__FILE__,line) (hres == S_OK, "get_offsetWidth failed: %08x\n", hres);
1079
1080     hres = IHTMLElement_get_offsetLeft(elem, &l);
1081     ok_(__FILE__,line) (hres == S_OK, "get_offsetLeft failed: %08x\n", hres);
1082
1083     hres = IHTMLElement_get_offsetParent(elem, &off_parent);
1084     ok_(__FILE__,line) (hres == S_OK, "get_offsetParent failed: %08x\n", hres);
1085
1086     _test_elem_tag(line, (IUnknown*)off_parent, parent_tag);
1087     IHTMLElement_Release(off_parent);
1088
1089     IHTMLElement_Release(elem);
1090 }
1091
1092 #define get_doc_node(d) _get_doc_node(__LINE__,d)
1093 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
1094 {
1095     IHTMLWindow2 *window;
1096     IHTMLDocument2 *ret;
1097     HRESULT hres;
1098
1099     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1100     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1101
1102     hres = IHTMLWindow2_get_document(window, &ret);
1103     ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres);
1104     ok_(__FILE__,line)(ret != NULL, "document = NULL\n");
1105
1106     return ret;
1107 }
1108
1109 #define test_window_name(d,e) _test_window_name(__LINE__,d,e)
1110 static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
1111 {
1112     BSTR name;
1113     HRESULT hres;
1114
1115     hres = IHTMLWindow2_get_name(window, &name);
1116     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1117     if(exname)
1118         ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
1119     else
1120         ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
1121     SysFreeString(name);
1122 }
1123
1124 #define set_window_name(w,n) _set_window_name(__LINE__,w,n)
1125 static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
1126 {
1127     BSTR str;
1128     HRESULT hres;
1129
1130     str = a2bstr(name);
1131     hres = IHTMLWindow2_put_name(window, str);
1132     SysFreeString(str);
1133     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1134
1135     _test_window_name(line, window, name);
1136 }
1137
1138 #define test_window_status(d) _test_window_status(__LINE__,d)
1139 static void _test_window_status(unsigned line, IHTMLWindow2 *window)
1140 {
1141     BSTR status;
1142     HRESULT hres;
1143
1144     status = (void*)0xdeadbeef;
1145     hres = IHTMLWindow2_get_status(window, &status);
1146     ok_(__FILE__,line)(hres == S_OK, "get_status failed: %08x\n", hres);
1147     ok_(__FILE__,line)(!status, "status = %s\n", wine_dbgstr_w(status));
1148     SysFreeString(status);
1149 }
1150
1151 #define set_window_status(w,n) _set_window_status(__LINE__,w,n)
1152 static void _set_window_status(unsigned line, IHTMLWindow2 *window, const char *status)
1153 {
1154     BSTR str;
1155     HRESULT hres;
1156
1157     str = a2bstr(status);
1158     hres = IHTMLWindow2_put_status(window, str);
1159     SysFreeString(str);
1160     ok_(__FILE__,line)(hres == S_OK, "put_status failed: %08x\n", hres);
1161 }
1162
1163 #define test_window_length(w,l) _test_window_length(__LINE__,w,l)
1164 static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
1165 {
1166     LONG length = -1;
1167     HRESULT hres;
1168
1169     hres = IHTMLWindow2_get_length(window, &length);
1170     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
1171     ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
1172 }
1173
1174 #define get_frame_content_window(e) _get_frame_content_window(__LINE__,e)
1175 static IHTMLWindow2 *_get_frame_content_window(unsigned line, IUnknown *elem)
1176 {
1177     IHTMLFrameBase2 *base2;
1178     IHTMLWindow2 *window;
1179     HRESULT hres;
1180
1181     hres = IUnknown_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
1182     ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
1183
1184     window = NULL;
1185     hres = IHTMLFrameBase2_get_contentWindow(base2, &window);
1186     IHTMLFrameBase2_Release(base2);
1187     ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
1188     ok(window != NULL, "contentWindow = NULL\n");
1189
1190     return window;
1191 }
1192
1193 static void test_get_set_attr(IHTMLDocument2 *doc)
1194 {
1195     IHTMLElement *elem;
1196     IHTMLDocument3 *doc3;
1197     HRESULT hres;
1198     BSTR bstr;
1199     VARIANT val;
1200
1201     /* grab an element to test with */
1202     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1203     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
1204
1205     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1206     IHTMLDocument3_Release(doc3);
1207     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
1208
1209     /* get a non-present attribute */
1210     bstr = a2bstr("notAnAttribute");
1211     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1212     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1213     ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val));
1214     VariantClear(&val);
1215     SysFreeString(bstr);
1216
1217     /* get a present attribute */
1218     bstr = a2bstr("scrollHeight");
1219     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1220     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1221     ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val));
1222     VariantClear(&val);
1223     SysFreeString(bstr);
1224
1225     /* create a new BSTR attribute */
1226     bstr = a2bstr("newAttribute");
1227
1228     V_VT(&val) = VT_BSTR;
1229     V_BSTR(&val) = a2bstr("the value");
1230     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1231     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1232     VariantClear(&val);
1233
1234     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1235     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1236     ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val));
1237     ok(strcmp_wa(V_BSTR(&val), "the value") == 0, "variant value should have been L\"the value\", was %s\n", wine_dbgstr_w(V_BSTR(&val)));
1238     VariantClear(&val);
1239
1240     /* overwrite the attribute with a BOOL */
1241     V_VT(&val) = VT_BOOL;
1242     V_BOOL(&val) = VARIANT_TRUE;
1243     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
1244     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1245     VariantClear(&val);
1246
1247     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1248     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1249     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1250     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1251     VariantClear(&val);
1252
1253     SysFreeString(bstr);
1254
1255     /* case-insensitive */
1256     bstr = a2bstr("newattribute");
1257     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1258     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1259     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1260     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1261     VariantClear(&val);
1262     SysFreeString(bstr);
1263
1264     IHTMLElement_Release(elem);
1265 }
1266
1267 #define get_doc_elem(d) _get_doc_elem(__LINE__,d)
1268 static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc)
1269 {
1270     IHTMLElement *elem;
1271     IHTMLDocument3 *doc3;
1272     HRESULT hres;
1273
1274     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1275     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
1276     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1277     ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres);
1278     IHTMLDocument3_Release(doc3);
1279
1280     return elem;
1281 }
1282
1283 #define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h)
1284 static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref)
1285 {
1286     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1287     BSTR str;
1288     HRESULT hres;
1289
1290     hres = IHTMLAnchorElement_get_href(anchor, &str);
1291     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1292     ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref);
1293     SysFreeString(str);
1294
1295     _test_disp_value(line, unk, exhref);
1296 }
1297
1298 #define test_anchor_put_href(a,h) _test_anchor_put_href(__LINE__,a,h)
1299 static void _test_anchor_put_href(unsigned line, IUnknown *unk, const char *exhref)
1300 {
1301     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1302     BSTR str;
1303     HRESULT hres;
1304
1305     str = a2bstr(exhref);
1306     hres = IHTMLAnchorElement_put_href(anchor, str);
1307     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1308     SysFreeString(str);
1309
1310     _test_disp_value(line, unk, exhref);
1311 }
1312
1313 #define test_anchor_get_target(a,h) _test_anchor_get_target(__LINE__,a,h)
1314 static void _test_anchor_get_target(unsigned line, IUnknown *unk, const char *target)
1315 {
1316     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1317     BSTR str;
1318     HRESULT hres;
1319
1320     hres = IHTMLAnchorElement_get_target(anchor, &str);
1321     ok_(__FILE__,line)(hres == S_OK, "get_target failed: %08x\n", hres);
1322     if(target)
1323         ok_(__FILE__,line)(!strcmp_wa(str, target), "target = %s, expected %s\n", wine_dbgstr_w(str), target);
1324     else
1325         ok_(__FILE__,line)(str == NULL, "target = %s, expected NULL\n", wine_dbgstr_w(str));
1326     SysFreeString(str);
1327 }
1328
1329 #define test_anchor_put_target(a,h) _test_anchor_put_target(__LINE__,a,h)
1330 static void _test_anchor_put_target(unsigned line, IUnknown *unk, const char *target)
1331 {
1332     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1333     BSTR str;
1334     HRESULT hres;
1335
1336     str = target ? a2bstr(target) : NULL;
1337     hres = IHTMLAnchorElement_put_target(anchor, str);
1338     ok_(__FILE__,line)(hres == S_OK, "put_target failed: %08x\n", hres);
1339     SysFreeString(str);
1340 }
1341
1342 #define test_anchor_name(a,h) _test_anchor_name(__LINE__,a,h)
1343 static void _test_anchor_name(unsigned line, IUnknown *unk, const char *name)
1344 {
1345     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1346     BSTR str;
1347     HRESULT hres;
1348
1349     hres = IHTMLAnchorElement_get_name(anchor, &str);
1350     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1351     if(name)
1352         ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
1353     else
1354         ok_(__FILE__,line)(str == NULL, "name = %s, expected NULL\n", wine_dbgstr_w(str));
1355     SysFreeString(str);
1356 }
1357
1358 #define test_anchor_put_name(a,h) _test_anchor_put_name(__LINE__,a,h)
1359 static void _test_anchor_put_name(unsigned line, IUnknown *unk, const char *name)
1360 {
1361     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1362     BSTR str;
1363     HRESULT hres;
1364
1365     str = name ? a2bstr(name) : NULL;
1366     hres = IHTMLAnchorElement_put_name(anchor, str);
1367     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1368     SysFreeString(str);
1369
1370     _test_anchor_name(line, unk, name);
1371 }
1372
1373
1374 #define test_option_text(o,t) _test_option_text(__LINE__,o,t)
1375 static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text)
1376 {
1377     BSTR bstr;
1378     HRESULT hres;
1379
1380     hres = IHTMLOptionElement_get_text(option, &bstr);
1381     ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres);
1382     ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr));
1383     SysFreeString(bstr);
1384 }
1385
1386 #define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t)
1387 static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text)
1388 {
1389     BSTR bstr;
1390     HRESULT hres;
1391
1392     bstr = a2bstr(text);
1393     hres = IHTMLOptionElement_put_text(option, bstr);
1394     SysFreeString(bstr);
1395     ok(hres == S_OK, "put_text failed: %08x\n", hres);
1396
1397     _test_option_text(line, option, text);
1398 }
1399
1400 #define test_option_value(o,t) _test_option_value(__LINE__,o,t)
1401 static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value)
1402 {
1403     BSTR bstr;
1404     HRESULT hres;
1405
1406     hres = IHTMLOptionElement_get_value(option, &bstr);
1407     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1408     ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr));
1409     SysFreeString(bstr);
1410 }
1411
1412 #define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t)
1413 static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value)
1414 {
1415     BSTR bstr;
1416     HRESULT hres;
1417
1418     bstr = a2bstr(value);
1419     hres = IHTMLOptionElement_put_value(option, bstr);
1420     SysFreeString(bstr);
1421     ok(hres == S_OK, "put_value failed: %08x\n", hres);
1422
1423     _test_option_value(line, option, value);
1424 }
1425
1426 #define test_option_selected(o,s) _test_option_selected(__LINE__,o,s)
1427 static void _test_option_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL ex)
1428 {
1429     VARIANT_BOOL b = 0x100;
1430     HRESULT hres;
1431
1432     hres = IHTMLOptionElement_get_selected(option, &b);
1433     ok_(__FILE__,line)(hres == S_OK, "get_selected failed: %08x\n", hres);
1434     ok_(__FILE__,line)(b == ex, "selected = %x, expected %x\n", b, ex);
1435 }
1436
1437 #define test_option_put_selected(o,s) _test_option_put_selected(__LINE__,o,s)
1438 static void _test_option_put_selected(unsigned line, IHTMLOptionElement *option, VARIANT_BOOL b)
1439 {
1440     HRESULT hres;
1441
1442     hres = IHTMLOptionElement_put_selected(option, b);
1443     ok_(__FILE__,line)(hres == S_OK, "put_selected failed: %08x\n", hres);
1444     _test_option_selected(line, option, b);
1445 }
1446
1447 #define test_textarea_value(t,v) _test_textarea_value(__LINE__,t,v)
1448 static void _test_textarea_value(unsigned line, IUnknown *unk, const char *exval)
1449 {
1450     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1451     BSTR value = (void*)0xdeadbeef;
1452     HRESULT hres;
1453
1454     hres = IHTMLTextAreaElement_get_value(textarea, &value);
1455     IHTMLTextAreaElement_Release(textarea);
1456     ok_(__FILE__,line)(hres == S_OK, "get_value failed: %08x\n", hres);
1457     if(exval)
1458         ok_(__FILE__,line)(!strcmp_wa(value, exval), "value = %s, expected %s\n", wine_dbgstr_w(value), exval);
1459     else
1460         ok_(__FILE__,line)(!value, "value = %p\n", value);
1461     SysFreeString(value);
1462 }
1463
1464 #define test_textarea_put_value(t,v) _test_textarea_put_value(__LINE__,t,v)
1465 static void _test_textarea_put_value(unsigned line, IUnknown *unk, const char *value)
1466 {
1467     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1468     BSTR tmp = a2bstr(value);
1469     HRESULT hres;
1470
1471     hres = IHTMLTextAreaElement_put_value(textarea, tmp);
1472     IHTMLTextAreaElement_Release(textarea);
1473     ok_(__FILE__,line)(hres == S_OK, "put_value failed: %08x\n", hres);
1474     SysFreeString(tmp);
1475
1476     _test_textarea_value(line, unk, value);
1477 }
1478
1479 #define test_textarea_readonly(t,v) _test_textarea_readonly(__LINE__,t,v)
1480 static void _test_textarea_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL ex)
1481 {
1482     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1483     VARIANT_BOOL b = 0x100;
1484     HRESULT hres;
1485
1486     hres = IHTMLTextAreaElement_get_readOnly(textarea, &b);
1487     IHTMLTextAreaElement_Release(textarea);
1488     ok_(__FILE__,line)(hres == S_OK, "get_readOnly failed: %08x\n", hres);
1489     ok_(__FILE__,line)(b == ex, "readOnly = %x, expected %x\n", b, ex);
1490 }
1491
1492 #define test_textarea_put_readonly(t,v) _test_textarea_put_readonly(__LINE__,t,v)
1493 static void _test_textarea_put_readonly(unsigned line, IUnknown *unk, VARIANT_BOOL b)
1494 {
1495     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1496     HRESULT hres;
1497
1498     hres = IHTMLTextAreaElement_put_readOnly(textarea, b);
1499     IHTMLTextAreaElement_Release(textarea);
1500     ok_(__FILE__,line)(hres == S_OK, "put_readOnly failed: %08x\n", hres);
1501
1502     _test_textarea_readonly(line, unk, b);
1503 }
1504
1505 #define test_textarea_type(t) _test_textarea_type(__LINE__,t)
1506 static void _test_textarea_type(unsigned line, IUnknown *unk)
1507 {
1508     IHTMLTextAreaElement *textarea = _get_textarea_iface(line, unk);
1509     BSTR type = (void*)0xdeadbeef;
1510     HRESULT hres;
1511
1512     hres = IHTMLTextAreaElement_get_type(textarea, &type);
1513     IHTMLTextAreaElement_Release(textarea);
1514     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
1515     ok_(__FILE__,line)(!strcmp_wa(type, "textarea"), "type = %s, expected textarea\n", wine_dbgstr_w(type));
1516     SysFreeString(type);
1517 }
1518
1519 #define test_comment_text(c,t) _test_comment_text(__LINE__,c,t)
1520 static void _test_comment_text(unsigned line, IUnknown *unk, const char *extext)
1521 {
1522     IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1523     BSTR text;
1524     HRESULT hres;
1525
1526     text = a2bstr(extext);
1527     hres = IHTMLCommentElement_get_text(comment, &text);
1528     ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
1529     ok_(__FILE__,line)(!strcmp_wa(text, extext), "text = \"%s\", expected \"%s\"\n", wine_dbgstr_w(text), extext);
1530
1531     IHTMLCommentElement_Release(comment);
1532     SysFreeString(text);
1533 }
1534
1535 #define test_comment_attrs(c) _test_comment_attrs(__LINE__,c)
1536 static void _test_comment_attrs(unsigned line, IUnknown *unk)
1537 {
1538     IHTMLCommentElement *comment = _get_comment_iface(__LINE__,unk);
1539     IHTMLElement *elem = _get_elem_iface(__LINE__,unk);
1540     IHTMLElement4 *elem4 = _get_elem4_iface(__LINE__,unk);
1541     IHTMLDOMAttribute *attr;
1542     BSTR name = a2bstr("test");
1543     VARIANT val;
1544     HRESULT hres;
1545
1546     hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1547     ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1548     ok(attr == NULL, "attr != NULL\n");
1549
1550     V_VT(&val) = VT_I4;
1551     V_I4(&val) = 1234;
1552     hres = IHTMLElement_setAttribute(elem, name, val, 0);
1553     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1554
1555     hres = IHTMLElement4_getAttributeNode(elem4, name, &attr);
1556     ok(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
1557     ok(attr != NULL, "attr == NULL\n");
1558
1559     IHTMLDOMAttribute_Release(attr);
1560     IHTMLCommentElement_Release(comment);
1561     IHTMLElement_Release(elem);
1562     IHTMLElement4_Release(elem4);
1563     SysFreeString(name);
1564 }
1565
1566 #define test_object_vspace(u,s) _test_object_vspace(__LINE__,u,s)
1567 static void _test_object_vspace(unsigned line, IUnknown *unk, LONG exl)
1568 {
1569     IHTMLObjectElement *object = _get_object_iface(line, unk);
1570     LONG l;
1571     HRESULT hres;
1572
1573     l = 0xdeadbeef;
1574     hres = IHTMLObjectElement_get_vspace(object, &l);
1575     ok_(__FILE__,line)(hres == S_OK, "get_vspace failed: %08x\n", hres);
1576     ok_(__FILE__,line)(l == exl, "vspace=%d, expected %d\n", l, exl);
1577     IHTMLObjectElement_Release(object);
1578 }
1579
1580 #define test_object_name(a,b) _test_object_name(__LINE__,a,b)
1581 static void _test_object_name(unsigned line, IHTMLElement *elem, const char *exname)
1582 {
1583     IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1584     BSTR str;
1585     HRESULT hres;
1586
1587     str = (void*)0xdeadbeef;
1588     hres = IHTMLObjectElement_get_name(object, &str);
1589     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
1590     if(exname)
1591         ok_(__FILE__,line)(!strcmp_wa(str, exname), "name=%s, expected %s\n", wine_dbgstr_w(str), exname);
1592     else
1593         ok_(__FILE__,line)(!str, "name=%s, expected NULL\n", wine_dbgstr_w(str));
1594     SysFreeString(str);
1595     IHTMLObjectElement_Release(object);
1596 }
1597
1598 #define set_object_name(a,b) _set_object_name(__LINE__,a,b)
1599 static void _set_object_name(unsigned line, IHTMLElement *elem, const char *name)
1600 {
1601     IHTMLObjectElement *object = _get_object_iface(line, (IUnknown*)elem);
1602     BSTR str;
1603     HRESULT hres;
1604
1605     str = a2bstr(name);
1606     hres = IHTMLObjectElement_put_name(object, str);
1607     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
1608     SysFreeString(str);
1609     IHTMLObjectElement_Release(object);
1610
1611     _test_object_name(line, elem, name);
1612 }
1613
1614 #define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v)
1615 static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc,
1616         const char *txt, const char *val)
1617 {
1618     IHTMLOptionElementFactory *factory;
1619     IHTMLOptionElement *option;
1620     IHTMLWindow2 *window;
1621     VARIANT text, value, empty;
1622     HRESULT hres;
1623
1624     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1625     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1626
1627     hres = IHTMLWindow2_get_Option(window, &factory);
1628     IHTMLWindow2_Release(window);
1629     ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres);
1630
1631     V_VT(&text) = VT_BSTR;
1632     V_BSTR(&text) = a2bstr(txt);
1633     V_VT(&value) = VT_BSTR;
1634     V_BSTR(&value) = a2bstr(val);
1635     V_VT(&empty) = VT_EMPTY;
1636
1637     hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option);
1638     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1639
1640     IHTMLOptionElementFactory_Release(factory);
1641     VariantClear(&text);
1642     VariantClear(&value);
1643
1644     _test_option_text(line, option, txt);
1645     _test_option_value(line, option, val);
1646     _test_option_selected(line, option, VARIANT_FALSE);
1647
1648     return option;
1649 }
1650
1651 #define test_img_width(o,w) _test_img_width(__LINE__,o,w)
1652 static void _test_img_width(unsigned line, IHTMLImgElement *img, const LONG exp)
1653 {
1654     LONG found = -1;
1655     HRESULT hres;
1656
1657     hres = IHTMLImgElement_get_width(img, &found);
1658     ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
1659     ok_(__FILE__,line) (found == exp, "width=%d\n", found);
1660 }
1661
1662 #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
1663 static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const LONG width)
1664 {
1665     HRESULT hres;
1666
1667     hres = IHTMLImgElement_put_width(img, width);
1668     ok(hres == S_OK, "put_width failed: %08x\n", hres);
1669
1670     _test_img_width(line, img, width);
1671 }
1672
1673 #define test_img_height(o,h) _test_img_height(__LINE__,o,h)
1674 static void _test_img_height(unsigned line, IHTMLImgElement *img, const LONG exp)
1675 {
1676     LONG found = -1;
1677     HRESULT hres;
1678
1679     hres = IHTMLImgElement_get_height(img, &found);
1680     ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
1681     ok_(__FILE__,line) (found == exp, "height=%d\n", found);
1682 }
1683
1684 #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
1685 static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const LONG height)
1686 {
1687     HRESULT hres;
1688
1689     hres = IHTMLImgElement_put_height(img, height);
1690     ok(hres == S_OK, "put_height failed: %08x\n", hres);
1691
1692     _test_img_height(line, img, height);
1693 }
1694
1695 #define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
1696 static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
1697         LONG wdth, LONG hght)
1698 {
1699     IHTMLImageElementFactory *factory;
1700     IHTMLImgElement *img;
1701     IHTMLWindow2 *window;
1702     VARIANT width, height;
1703     char buf[16];
1704     HRESULT hres;
1705
1706     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1707     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1708
1709     hres = IHTMLWindow2_get_Image(window, &factory);
1710     IHTMLWindow2_Release(window);
1711     ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
1712
1713     test_ifaces((IUnknown*)factory, img_factory_iids);
1714     test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
1715
1716     if(wdth >= 0){
1717         snprintf(buf, 16, "%d", wdth);
1718         V_VT(&width) = VT_BSTR;
1719         V_BSTR(&width) = a2bstr(buf);
1720     }else{
1721         V_VT(&width) = VT_EMPTY;
1722         wdth = 0;
1723     }
1724
1725     if(hght >= 0){
1726         snprintf(buf, 16, "%d", hght);
1727         V_VT(&height) = VT_BSTR;
1728         V_BSTR(&height) = a2bstr(buf);
1729     }else{
1730         V_VT(&height) = VT_EMPTY;
1731         hght = 0;
1732     }
1733
1734     hres = IHTMLImageElementFactory_create(factory, width, height, &img);
1735     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1736
1737     IHTMLImageElementFactory_Release(factory);
1738     VariantClear(&width);
1739     VariantClear(&height);
1740
1741     if(SUCCEEDED(hres)) {
1742         _test_img_width(line, img, wdth);
1743         _test_img_height(line, img, hght);
1744         return img;
1745     }
1746
1747     return NULL;
1748 }
1749
1750 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
1751 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
1752 {
1753     LONG len = 0xdeadbeef;
1754     HRESULT hres;
1755
1756     hres = IHTMLSelectElement_get_length(select, &len);
1757     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1758     ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length);
1759 }
1760
1761 #define test_select_put_length(s,l) _test_select_put_length(__LINE__,s,l)
1762 static void _test_select_put_length(unsigned line, IUnknown *unk, LONG length)
1763 {
1764     IHTMLSelectElement *select = _get_select_iface(line, unk);
1765     HRESULT hres;
1766
1767     hres = IHTMLSelectElement_put_length(select, length);
1768     ok_(__FILE__,line) (hres == S_OK, "put_length failed: %08x\n", hres);
1769     _test_select_length(line, select, length);
1770     IHTMLSelectElement_Release(select);
1771 }
1772
1773 #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i)
1774 static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1775 {
1776     LONG idx = 0xdeadbeef;
1777     HRESULT hres;
1778
1779     hres = IHTMLSelectElement_get_selectedIndex(select, &idx);
1780     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1781     ok_(__FILE__,line) (idx == index, "idx=%d, expected %d\n", idx, index);
1782 }
1783
1784 #define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i)
1785 static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1786 {
1787     HRESULT hres;
1788
1789     hres = IHTMLSelectElement_put_selectedIndex(select, index);
1790     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1791     _test_select_selidx(line, select, index);
1792 }
1793
1794 #define test_select_value(s,v) _test_select_value(__LINE__,s,v)
1795 static void _test_select_value(unsigned line, IHTMLSelectElement *select, const char *exval)
1796 {
1797     BSTR val;
1798     HRESULT hres;
1799
1800     hres = IHTMLSelectElement_get_value(select, &val);
1801     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1802     if(exval)
1803         ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val));
1804     else
1805         ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val));
1806     SysFreeString(val);
1807 }
1808
1809 #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v)
1810 static void _test_select_set_value(unsigned line, IHTMLSelectElement *select, const char *val)
1811 {
1812     BSTR bstr;
1813     HRESULT hres;
1814
1815     bstr = a2bstr(val);
1816     hres = IHTMLSelectElement_put_value(select, bstr);
1817     SysFreeString(bstr);
1818     ok_(__FILE__,line) (hres == S_OK, "put_value failed: %08x\n", hres);
1819 }
1820
1821 #define test_select_type(s,t) _test_select_type(__LINE__,s,t)
1822 static void _test_select_type(unsigned line, IHTMLSelectElement *select, const char *extype)
1823 {
1824     BSTR type;
1825     HRESULT hres;
1826
1827     hres = IHTMLSelectElement_get_type(select, &type);
1828     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
1829     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
1830     SysFreeString(type);
1831 }
1832
1833 #define test_range_text(r,t) _test_range_text(__LINE__,r,t)
1834 static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext)
1835 {
1836     BSTR text;
1837     HRESULT hres;
1838
1839     hres = IHTMLTxtRange_get_text(range, &text);
1840     ok_(__FILE__, line) (hres == S_OK, "get_text failed: %08x\n", hres);
1841
1842     if(extext) {
1843         ok_(__FILE__, line) (text != NULL, "text == NULL\n");
1844         ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext);
1845     }else {
1846         ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text));
1847     }
1848
1849     SysFreeString(text);
1850
1851 }
1852
1853 #define test_range_collapse(r,b) _test_range_collapse(__LINE__,r,b)
1854 static void _test_range_collapse(unsigned line, IHTMLTxtRange *range, BOOL b)
1855 {
1856     HRESULT hres;
1857
1858     hres = IHTMLTxtRange_collapse(range, b);
1859     ok_(__FILE__, line) (hres == S_OK, "collapse failed: %08x\n", hres);
1860     _test_range_text(line, range, NULL);
1861 }
1862
1863 #define test_range_expand(r,u,b,t) _test_range_expand(__LINE__,r,u,b,t)
1864 static void _test_range_expand(unsigned line, IHTMLTxtRange *range, LPWSTR unit,
1865         VARIANT_BOOL exb, const char *extext)
1866 {
1867     VARIANT_BOOL b = 0xe0e0;
1868     HRESULT hres;
1869
1870     hres = IHTMLTxtRange_expand(range, unit, &b);
1871     ok_(__FILE__,line) (hres == S_OK, "expand failed: %08x\n", hres);
1872     ok_(__FILE__,line) (b == exb, "b=%x, expected %x\n", b, exb);
1873     _test_range_text(line, range, extext);
1874 }
1875
1876 #define test_range_move(r,u,c,e) _test_range_move(__LINE__,r,u,c,e)
1877 static void _test_range_move(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1878 {
1879     LONG c = 0xdeadbeef;
1880     HRESULT hres;
1881
1882     hres = IHTMLTxtRange_move(range, unit, cnt, &c);
1883     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1884     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1885     _test_range_text(line, range, NULL);
1886 }
1887
1888 #define test_range_movestart(r,u,c,e) _test_range_movestart(__LINE__,r,u,c,e)
1889 static void _test_range_movestart(unsigned line, IHTMLTxtRange *range,
1890         LPWSTR unit, LONG cnt, LONG excnt)
1891 {
1892     LONG c = 0xdeadbeef;
1893     HRESULT hres;
1894
1895     hres = IHTMLTxtRange_moveStart(range, unit, cnt, &c);
1896     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1897     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1898 }
1899
1900 #define test_range_moveend(r,u,c,e) _test_range_moveend(__LINE__,r,u,c,e)
1901 static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1902 {
1903     LONG c = 0xdeadbeef;
1904     HRESULT hres;
1905
1906     hres = IHTMLTxtRange_moveEnd(range, unit, cnt, &c);
1907     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1908     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1909 }
1910
1911 #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
1912 static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
1913 {
1914     HRESULT hres;
1915     BSTR bstr = a2bstr(text);
1916
1917     hres = IHTMLTxtRange_put_text(range, bstr);
1918     ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
1919     SysFreeString(bstr);
1920     _test_range_text(line, range, NULL);
1921 }
1922
1923 #define test_range_inrange(r1,r2,b) _test_range_inrange(__LINE__,r1,r2,b)
1924 static void _test_range_inrange(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1925 {
1926     VARIANT_BOOL b;
1927     HRESULT hres;
1928
1929     b = 0xe0e0;
1930     hres = IHTMLTxtRange_inRange(range1, range2, &b);
1931     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1932     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1933 }
1934
1935 #define test_range_isequal(r1,r2,b) _test_range_isequal(__LINE__,r1,r2,b)
1936 static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1937 {
1938     VARIANT_BOOL b;
1939     HRESULT hres;
1940
1941     b = 0xe0e0;
1942     hres = IHTMLTxtRange_isEqual(range1, range2, &b);
1943     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1944     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1945
1946     b = 0xe0e0;
1947     hres = IHTMLTxtRange_isEqual(range2, range1, &b);
1948     ok_(__FILE__,line) (hres == S_OK, "(2->1) isEqual failed: %08x\n", hres);
1949     ok_(__FILE__,line) (b == exb, "(2->1) b=%x, expected %x\n", b, exb);
1950
1951     if(exb) {
1952         test_range_inrange(range1, range2, VARIANT_TRUE);
1953         test_range_inrange(range2, range1, VARIANT_TRUE);
1954     }
1955 }
1956
1957 #define test_range_parent(r,t) _test_range_parent(__LINE__,r,t)
1958 static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t type)
1959 {
1960     IHTMLElement *elem;
1961     HRESULT hres;
1962
1963     hres = IHTMLTxtRange_parentElement(range, &elem);
1964     ok_(__FILE__,line) (hres == S_OK, "parentElement failed: %08x\n", hres);
1965
1966     _test_elem_type(line, (IUnknown*)elem, type);
1967
1968     IHTMLElement_Release(elem);
1969 }
1970
1971 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
1972 static void _test_elem_collection(unsigned line, IUnknown *unk,
1973         const elem_type_t *elem_types, LONG exlen)
1974 {
1975     IHTMLElementCollection *col;
1976     LONG len;
1977     DWORD i;
1978     VARIANT name, index;
1979     IDispatch *disp, *disp2;
1980     HRESULT hres;
1981
1982     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col);
1983     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres);
1984
1985     test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]");
1986
1987     hres = IHTMLElementCollection_get_length(col, &len);
1988     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1989     ok_(__FILE__,line) (len == exlen, "len=%d, expected %d\n", len, exlen);
1990
1991     if(len > exlen)
1992         len = exlen;
1993
1994     V_VT(&index) = VT_EMPTY;
1995
1996     for(i=0; i<len; i++) {
1997         V_VT(&name) = VT_I4;
1998         V_I4(&name) = i;
1999         disp = (void*)0xdeadbeef;
2000         hres = IHTMLElementCollection_item(col, name, index, &disp);
2001         ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2002         ok_(__FILE__,line) (disp != NULL, "item returned NULL\n");
2003         if(FAILED(hres) || !disp)
2004             continue;
2005
2006         _test_elem_type(line, (IUnknown*)disp, elem_types[i]);
2007
2008         if(!i) {
2009             V_VT(&name) = VT_UINT;
2010             V_I4(&name) = 0;
2011             disp2 = (void*)0xdeadbeef;
2012             hres = IHTMLElementCollection_item(col, name, index, &disp2);
2013             ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
2014             ok_(__FILE__,line) (iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
2015             if(disp2)
2016                 IDispatch_Release(disp2);
2017         }
2018
2019         IDispatch_Release(disp);
2020     }
2021
2022     V_VT(&name) = VT_I4;
2023     V_I4(&name) = len;
2024     disp = (void*)0xdeadbeef;
2025     hres = IHTMLElementCollection_item(col, name, index, &disp);
2026     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
2027     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2028
2029     V_VT(&name) = VT_I4;
2030     V_I4(&name) = -1;
2031     disp = (void*)0xdeadbeef;
2032     hres = IHTMLElementCollection_item(col, name, index, &disp);
2033     ok_(__FILE__,line) (hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
2034     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
2035
2036     IHTMLElementCollection_Release(col);
2037 }
2038
2039 #define test_elem_all(c,t,l) _test_elem_all(__LINE__,c,t,l)
2040 static void _test_elem_all(unsigned line, IUnknown *unk, const elem_type_t *elem_types, LONG exlen)
2041 {
2042     IHTMLElement *elem = _get_elem_iface(line, unk);
2043     IDispatch *disp;
2044     HRESULT hres;
2045
2046     hres = IHTMLElement_get_all(elem, &disp);
2047     IHTMLElement_Release(elem);
2048     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2049
2050     _test_elem_collection(line, (IUnknown*)disp, elem_types, exlen);
2051     IDispatch_Release(disp);
2052 }
2053
2054 #define test_doc_all(a,b,c) _test_doc_all(__LINE__,a,b,c)
2055 static void _test_doc_all(unsigned line, IHTMLDocument2 *doc, const elem_type_t *elem_types, LONG exlen)
2056 {
2057     IHTMLElementCollection *col;
2058     HRESULT hres;
2059
2060     hres = IHTMLDocument2_get_all(doc, &col);
2061     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
2062
2063     _test_elem_collection(line, (IUnknown*)col, elem_types, exlen);
2064     IHTMLElementCollection_Release(col);
2065 }
2066
2067 #define test_elem_getelembytag(a,b,c,d) _test_elem_getelembytag(__LINE__,a,b,c,d)
2068 static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t type, LONG exlen, IHTMLElement **ret)
2069 {
2070     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2071     IHTMLElementCollection *col = NULL;
2072     elem_type_t *types = NULL;
2073     BSTR tmp;
2074     int i;
2075     HRESULT hres;
2076
2077     tmp = a2bstr(elem_type_infos[type].tag);
2078     hres = IHTMLElement2_getElementsByTagName(elem, tmp, &col);
2079     SysFreeString(tmp);
2080     IHTMLElement2_Release(elem);
2081     ok_(__FILE__,line) (hres == S_OK, "getElementByTagName failed: %08x\n", hres);
2082     ok_(__FILE__,line) (col != NULL, "col == NULL\n");
2083
2084     if(exlen) {
2085         types = HeapAlloc(GetProcessHeap(), 0, exlen*sizeof(elem_type_t));
2086         for(i=0; i<exlen; i++)
2087             types[i] = type;
2088     }
2089
2090     _test_elem_collection(line, (IUnknown*)col, types, exlen);
2091
2092     HeapFree(GetProcessHeap(), 0, types);
2093
2094     if(ret) {
2095         IDispatch *disp;
2096         VARIANT v;
2097
2098         V_VT(&v) = VT_I4;
2099         V_I4(&v) = 0;
2100         disp = NULL;
2101         hres = IHTMLElementCollection_item(col, v, v, &disp);
2102         ok(hres == S_OK, "item failed: %08x\n", hres);
2103         ok(disp != NULL, "disp == NULL\n");
2104         *ret = _get_elem_iface(line, (IUnknown*)disp);
2105         IDispatch_Release(disp);
2106     }
2107
2108     IHTMLElementCollection_Release(col);
2109 }
2110
2111 #define test_elem_innertext(e,t) _test_elem_innertext(__LINE__,e,t)
2112 static void _test_elem_innertext(unsigned line, IHTMLElement *elem, const char *extext)
2113 {
2114     BSTR text = NULL;
2115     HRESULT hres;
2116
2117     hres = IHTMLElement_get_innerText(elem, &text);
2118     ok_(__FILE__,line) (hres == S_OK, "get_innerText failed: %08x\n", hres);
2119     if(extext)
2120         ok_(__FILE__,line) (!strcmp_wa(text, extext), "get_innerText returned %s expected %s\n",
2121                             wine_dbgstr_w(text), extext);
2122     else
2123         ok_(__FILE__,line) (!text, "get_innerText returned %s expected NULL\n", wine_dbgstr_w(text));
2124     SysFreeString(text);
2125 }
2126
2127 #define test_elem_set_innertext(e,t) _test_elem_set_innertext(__LINE__,e,t)
2128 static void _test_elem_set_innertext(unsigned line, IHTMLElement *elem, const char *text)
2129 {
2130     IHTMLDOMChildrenCollection *col;
2131     BSTR str;
2132     HRESULT hres;
2133
2134     str = a2bstr(text);
2135     hres = IHTMLElement_put_innerText(elem, str);
2136     ok_(__FILE__,line) (hres == S_OK, "put_innerText failed: %08x\n", hres);
2137     SysFreeString(str);
2138
2139     _test_elem_innertext(line, elem, text);
2140
2141
2142     col = _get_child_nodes(line, (IUnknown*)elem);
2143     ok(col != NULL, "col == NULL\n");
2144     if(col) {
2145         LONG length = 0, type;
2146         IHTMLDOMNode *node;
2147
2148         hres = IHTMLDOMChildrenCollection_get_length(col, &length);
2149         ok(hres == S_OK, "get_length failed: %08x\n", hres);
2150         ok(length == 1, "length = %d\n", length);
2151
2152         node = _get_child_item(line, col, 0);
2153         ok(node != NULL, "node == NULL\n");
2154         if(node) {
2155             type = _get_node_type(line, (IUnknown*)node);
2156             ok(type == 3, "type=%d\n", type);
2157             IHTMLDOMNode_Release(node);
2158         }
2159
2160         IHTMLDOMChildrenCollection_Release(col);
2161     }
2162
2163 }
2164
2165 #define test_elem_innerhtml(e,t) _test_elem_innerhtml(__LINE__,e,t)
2166 static void _test_elem_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2167 {
2168     IHTMLElement *elem = _get_elem_iface(line, unk);
2169     BSTR html;
2170     HRESULT hres;
2171
2172     hres = IHTMLElement_get_innerHTML(elem, &html);
2173     ok_(__FILE__,line)(hres == S_OK, "get_innerHTML failed: %08x\n", hres);
2174     if(inner_html)
2175         ok_(__FILE__,line)(!strcmp_wa(html, inner_html), "unexpected innerHTML: %s\n", wine_dbgstr_w(html));
2176     else
2177         ok_(__FILE__,line)(!html, "innerHTML = %s\n", wine_dbgstr_w(html));
2178
2179     IHTMLElement_Release(elem);
2180     SysFreeString(html);
2181 }
2182
2183 #define test_elem_set_innerhtml(e,t) _test_elem_set_innerhtml(__LINE__,e,t)
2184 static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
2185 {
2186     IHTMLElement *elem = _get_elem_iface(line, unk);
2187     BSTR html;
2188     HRESULT hres;
2189
2190     html = a2bstr(inner_html);
2191     hres = IHTMLElement_put_innerHTML(elem, html);
2192     ok_(__FILE__,line)(hres == S_OK, "put_innerHTML failed: %08x\n", hres);
2193
2194     IHTMLElement_Release(elem);
2195     SysFreeString(html);
2196 }
2197
2198 #define test_elem_set_outerhtml(e,t) _test_elem_set_outerhtml(__LINE__,e,t)
2199 static void _test_elem_set_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2200 {
2201     IHTMLElement *elem = _get_elem_iface(line, unk);
2202     BSTR html;
2203     HRESULT hres;
2204
2205     html = a2bstr(outer_html);
2206     hres = IHTMLElement_put_outerHTML(elem, html);
2207     ok_(__FILE__,line)(hres == S_OK, "put_outerHTML failed: %08x\n", hres);
2208
2209     IHTMLElement_Release(elem);
2210     SysFreeString(html);
2211 }
2212
2213 #define test_elem_outerhtml(e,t) _test_elem_outerhtml(__LINE__,e,t)
2214 static void _test_elem_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
2215 {
2216     IHTMLElement *elem = _get_elem_iface(line, unk);
2217     BSTR html;
2218     HRESULT hres;
2219
2220     hres = IHTMLElement_get_outerHTML(elem, &html);
2221     ok_(__FILE__,line)(hres == S_OK, "get_outerHTML failed: %08x\n", hres);
2222     ok_(__FILE__,line)(!strcmp_wa(html, outer_html), "outerHTML = '%s', expected '%s'\n", wine_dbgstr_w(html), outer_html);
2223
2224     IHTMLElement_Release(elem);
2225     SysFreeString(html);
2226 }
2227
2228 #define test_elem_contains(a,b,c) _test_elem_contains(__LINE__,a,b,c)
2229 static void _test_elem_contains(unsigned line, IHTMLElement *elem, IHTMLElement *elem2, VARIANT_BOOL exval)
2230 {
2231     VARIANT_BOOL b;
2232     HRESULT hres;
2233
2234     b = 100;
2235     hres = IHTMLElement_contains(elem, elem2, &b);
2236     ok_(__FILE__,line)(hres == S_OK, "contains failed: %08x\n", hres);
2237     ok_(__FILE__,line)(b == exval, "contains returned %x, expected %x\n", b, exval);
2238 }
2239
2240 #define get_first_child(n) _get_first_child(__LINE__,n)
2241 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
2242 {
2243     IHTMLDOMNode *node = _get_node_iface(line, unk);
2244     IHTMLDOMNode *child = NULL;
2245     HRESULT hres;
2246
2247     hres = IHTMLDOMNode_get_firstChild(node, &child);
2248     IHTMLDOMNode_Release(node);
2249     ok_(__FILE__,line) (hres == S_OK, "get_firstChild failed: %08x\n", hres);
2250
2251     return child;
2252 }
2253
2254 #define test_node_has_child(u,b) _test_node_has_child(__LINE__,u,b)
2255 static void _test_node_has_child(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2256 {
2257     IHTMLDOMNode *node = _get_node_iface(line, unk);
2258     VARIANT_BOOL b = 0xdead;
2259     HRESULT hres;
2260
2261     hres = IHTMLDOMNode_hasChildNodes(node, &b);
2262     ok_(__FILE__,line) (hres == S_OK, "hasChildNodes failed: %08x\n", hres);
2263     ok_(__FILE__,line) (b == exb, "hasChildNodes=%x, expected %x\n", b, exb);
2264
2265     IHTMLDOMNode_Release(node);
2266 }
2267
2268 #define test_node_get_parent(u) _test_node_get_parent(__LINE__,u)
2269 static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
2270 {
2271     IHTMLDOMNode *node = _get_node_iface(line, unk);
2272     IHTMLDOMNode *parent;
2273     HRESULT hres;
2274
2275     hres = IHTMLDOMNode_get_parentNode(node, &parent);
2276     IHTMLDOMNode_Release(node);
2277     ok_(__FILE__,line) (hres == S_OK, "get_parentNode failed: %08x\n", hres);
2278
2279     return parent;
2280 }
2281
2282 #define node_get_next(u) _node_get_next(__LINE__,u)
2283 static IHTMLDOMNode *_node_get_next(unsigned line, IUnknown *unk)
2284 {
2285     IHTMLDOMNode *node = _get_node_iface(line, unk);
2286     IHTMLDOMNode *next;
2287     HRESULT hres;
2288
2289     hres = IHTMLDOMNode_get_nextSibling(node, &next);
2290     IHTMLDOMNode_Release(node);
2291     ok_(__FILE__,line) (hres == S_OK, "get_nextSiblibg failed: %08x\n", hres);
2292
2293     return next;
2294 }
2295
2296 #define node_get_prev(u) _node_get_prev(__LINE__,u)
2297 static IHTMLDOMNode *_node_get_prev(unsigned line, IUnknown *unk)
2298 {
2299     IHTMLDOMNode *node = _get_node_iface(line, unk);
2300     IHTMLDOMNode *prev;
2301     HRESULT hres;
2302
2303     hres = IHTMLDOMNode_get_previousSibling(node, &prev);
2304     IHTMLDOMNode_Release(node);
2305     ok_(__FILE__,line) (hres == S_OK, "get_previousSibling failed: %08x\n", hres);
2306
2307     return prev;
2308 }
2309
2310 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
2311 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
2312 {
2313     IHTMLElement *elem = _get_elem_iface(line, unk);
2314     IHTMLElement *parent;
2315     HRESULT hres;
2316
2317     hres = IHTMLElement_get_parentElement(elem, &parent);
2318     IHTMLElement_Release(elem);
2319     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
2320
2321     return parent;
2322 }
2323
2324 #define test_elem3_get_disabled(i,b) _test_elem3_get_disabled(__LINE__,i,b)
2325 static void _test_elem3_get_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
2326 {
2327     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2328     VARIANT_BOOL disabled = 100;
2329     HRESULT hres;
2330
2331     if (!elem3) return;
2332     hres = IHTMLElement3_get_disabled(elem3, &disabled);
2333     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2334     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2335     IHTMLElement3_Release(elem3);
2336 }
2337
2338 #define test_elem3_set_disabled(i,b) _test_elem3_set_disabled(__LINE__,i,b)
2339 static void _test_elem3_set_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL b)
2340 {
2341     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
2342     HRESULT hres;
2343
2344     if (!elem3) return;
2345     hres = IHTMLElement3_put_disabled(elem3, b);
2346     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2347
2348     IHTMLElement3_Release(elem3);
2349     _test_elem3_get_disabled(line, unk, b);
2350 }
2351
2352 #define test_select_get_disabled(i,b) _test_select_get_disabled(__LINE__,i,b)
2353 static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exb)
2354 {
2355     VARIANT_BOOL disabled = 100;
2356     HRESULT hres;
2357
2358     hres = IHTMLSelectElement_get_disabled(select, &disabled);
2359     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2360     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2361
2362     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
2363 }
2364
2365 #define test_text_length(u,l) _test_text_length(__LINE__,u,l)
2366 static void _test_text_length(unsigned line, IUnknown *unk, LONG l)
2367 {
2368     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
2369     LONG length;
2370     HRESULT hres;
2371
2372     hres = IHTMLDOMTextNode_get_length(text, &length);
2373     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
2374     ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l);
2375     IHTMLDOMTextNode_Release(text);
2376 }
2377
2378 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
2379 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
2380 {
2381     HRESULT hres;
2382
2383     hres = IHTMLSelectElement_put_disabled(select, b);
2384     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2385
2386     _test_select_get_disabled(line, select, b);
2387 }
2388
2389 #define elem_get_scroll_height(u) _elem_get_scroll_height(__LINE__,u)
2390 static LONG _elem_get_scroll_height(unsigned line, IUnknown *unk)
2391 {
2392     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2393     IHTMLTextContainer *txtcont;
2394     LONG l = -1, l2 = -1;
2395     HRESULT hres;
2396
2397     hres = IHTMLElement2_get_scrollHeight(elem, &l);
2398     ok_(__FILE__,line) (hres == S_OK, "get_scrollHeight failed: %08x\n", hres);
2399     IHTMLElement2_Release(elem);
2400
2401     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2402     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2403
2404     hres = IHTMLTextContainer_get_scrollHeight(txtcont, &l2);
2405     IHTMLTextContainer_Release(txtcont);
2406     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollHeight failed: %d\n", l2);
2407     ok_(__FILE__,line) (l == l2, "unexpected height %d, expected %d\n", l2, l);
2408
2409     return l;
2410 }
2411
2412 #define elem_get_scroll_width(u) _elem_get_scroll_width(__LINE__,u)
2413 static LONG _elem_get_scroll_width(unsigned line, IUnknown *unk)
2414 {
2415     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2416     IHTMLTextContainer *txtcont;
2417     LONG l = -1, l2 = -1;
2418     HRESULT hres;
2419
2420     hres = IHTMLElement2_get_scrollWidth(elem, &l);
2421     ok_(__FILE__,line) (hres == S_OK, "get_scrollWidth failed: %08x\n", hres);
2422     IHTMLElement2_Release(elem);
2423
2424     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2425     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2426
2427     hres = IHTMLTextContainer_get_scrollWidth(txtcont, &l2);
2428     IHTMLTextContainer_Release(txtcont);
2429     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollWidth failed: %d\n", l2);
2430     ok_(__FILE__,line) (l == l2, "unexpected width %d, expected %d\n", l2, l);
2431
2432     return l;
2433 }
2434
2435 #define elem_get_scroll_top(u) _elem_get_scroll_top(__LINE__,u)
2436 static LONG _elem_get_scroll_top(unsigned line, IUnknown *unk)
2437 {
2438     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2439     IHTMLTextContainer *txtcont;
2440     LONG l = -1, l2 = -1;
2441     HRESULT hres;
2442
2443     hres = IHTMLElement2_get_scrollTop(elem, &l);
2444     ok_(__FILE__,line) (hres == S_OK, "get_scrollTop failed: %08x\n", hres);
2445     IHTMLElement2_Release(elem);
2446
2447     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2448     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2449
2450     hres = IHTMLTextContainer_get_scrollTop(txtcont, &l2);
2451     IHTMLTextContainer_Release(txtcont);
2452     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollTop failed: %d\n", l2);
2453     ok_(__FILE__,line) (l == l2, "unexpected top %d, expected %d\n", l2, l);
2454
2455     return l;
2456 }
2457
2458 #define elem_get_scroll_left(u) _elem_get_scroll_left(__LINE__,u)
2459 static void _elem_get_scroll_left(unsigned line, IUnknown *unk)
2460 {
2461     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2462     IHTMLTextContainer *txtcont;
2463     LONG l = -1, l2 = -1;
2464     HRESULT hres;
2465
2466     hres = IHTMLElement2_get_scrollLeft(elem, NULL);
2467     ok(hres == E_INVALIDARG, "expect E_INVALIDARG got 0x%08x\n", hres);
2468
2469     hres = IHTMLElement2_get_scrollLeft(elem, &l);
2470     ok(hres == S_OK, "get_scrollTop failed: %08x\n", hres);
2471     IHTMLElement2_Release(elem);
2472
2473     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
2474     ok(hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
2475
2476     hres = IHTMLTextContainer_get_scrollLeft(txtcont, &l2);
2477     IHTMLTextContainer_Release(txtcont);
2478     ok(hres == S_OK, "IHTMLTextContainer::get_scrollLeft failed: %d\n", l2);
2479     ok(l == l2, "unexpected left %d, expected %d\n", l2, l);
2480 }
2481
2482 #define test_img_src(a,b,c) _test_img_src(__LINE__,a,b,c)
2483 static void _test_img_src(unsigned line, IUnknown *unk, const char *exsrc, const char *broken_src)
2484 {
2485     IHTMLImgElement *img = _get_img_iface(line, unk);
2486     BSTR src;
2487     HRESULT hres;
2488
2489     hres = IHTMLImgElement_get_src(img, &src);
2490     IHTMLImgElement_Release(img);
2491     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
2492     ok_(__FILE__,line) (!strcmp_wa(src, exsrc) || (broken_src && broken(!strcmp_wa(src, broken_src))),
2493         "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
2494     SysFreeString(src);
2495 }
2496
2497 #define test_img_set_src(u,s) _test_img_set_src(__LINE__,u,s)
2498 static void _test_img_set_src(unsigned line, IUnknown *unk, const char *src)
2499 {
2500     IHTMLImgElement *img = _get_img_iface(line, unk);
2501     BSTR tmp;
2502     HRESULT hres;
2503
2504     tmp = a2bstr(src);
2505     hres = IHTMLImgElement_put_src(img, tmp);
2506     IHTMLImgElement_Release(img);
2507     SysFreeString(tmp);
2508     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
2509 }
2510
2511 #define test_img_alt(u,a) _test_img_alt(__LINE__,u,a)
2512 static void _test_img_alt(unsigned line, IUnknown *unk, const char *exalt)
2513 {
2514     IHTMLImgElement *img = _get_img_iface(line, unk);
2515     BSTR alt;
2516     HRESULT hres;
2517
2518     hres = IHTMLImgElement_get_alt(img, &alt);
2519     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
2520     if(exalt)
2521         ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "inexopected alt %s\n", wine_dbgstr_w(alt));
2522     else
2523         ok_(__FILE__,line) (!alt, "alt != NULL\n");
2524     SysFreeString(alt);
2525 }
2526
2527 #define test_img_set_alt(u,a) _test_img_set_alt(__LINE__,u,a)
2528 static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
2529 {
2530     IHTMLImgElement *img = _get_img_iface(line, unk);
2531     BSTR tmp;
2532     HRESULT hres;
2533
2534     tmp = a2bstr(alt);
2535     hres = IHTMLImgElement_put_alt(img, tmp);
2536     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
2537     SysFreeString(tmp);
2538
2539     _test_img_alt(line, unk, alt);
2540 }
2541
2542 #define test_img_name(u, c) _test_img_name(__LINE__,u, c)
2543 static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue)
2544 {
2545     IHTMLImgElement *img = _get_img_iface(line, unk);
2546     BSTR sName;
2547     HRESULT hres;
2548
2549     hres = IHTMLImgElement_get_name(img, &sName);
2550     ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres);
2551     ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName));
2552     IHTMLImgElement_Release(img);
2553     SysFreeString(sName);
2554 }
2555
2556 #define test_img_complete(a,b) _test_img_complete(__LINE__,a,b)
2557 static void _test_img_complete(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
2558 {
2559     IHTMLImgElement *img = _get_img_iface(line, (IUnknown*)elem);
2560     VARIANT_BOOL b = 100;
2561     HRESULT hres;
2562
2563     hres = IHTMLImgElement_get_complete(img, &b);
2564     ok_(__FILE__,line) (hres == S_OK, "get_complete failed: %08x\n", hres);
2565     ok_(__FILE__,line) (b == exb, "complete = %x, expected %x\n", b, exb);
2566     IHTMLImgElement_Release(img);
2567 }
2568
2569 static void test_dynamic_properties(IHTMLElement *elem)
2570 {
2571     static const WCHAR attr1W[] = {'a','t','t','r','1',0};
2572     IDispatchEx *dispex;
2573     BSTR name, attr1 = SysAllocString(attr1W);
2574     VARIANT_BOOL succ;
2575     VARIANT val;
2576     int checked_no = 0;
2577     DISPID id = DISPID_STARTENUM;
2578     HRESULT hres;
2579
2580     hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
2581     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2582
2583     hres = IHTMLElement_removeAttribute(elem, attr1, 0, &succ);
2584     ok(hres == S_OK, "removeAttribute failed: %08x\n", hres);
2585     ok(succ, "removeAttribute set succ to FALSE\n");
2586
2587     while(1) {
2588         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, id, &id);
2589         ok(hres==S_OK || hres==S_FALSE, "GetNextDispID failed: %08x\n", hres);
2590         if(hres != S_OK)
2591             break;
2592
2593         hres = IDispatchEx_GetMemberName(dispex, id, &name);
2594         ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
2595
2596         if(!strcmp_wa(name, "attr1"))
2597             ok(0, "attr1 should be removed\n");
2598         else if(!strcmp_wa(name, "attr2") || !strcmp_wa(name, "attr3"))
2599             checked_no++;
2600         SysFreeString(name);
2601     }
2602     ok(checked_no == 2, "checked_no=%d, expected 2\n", checked_no);
2603     IDispatchEx_Release(dispex);
2604
2605     V_VT(&val) = VT_BSTR;
2606     V_BSTR(&val) = attr1;
2607     hres = IHTMLElement_setAttribute(elem, attr1, val, 0);
2608     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
2609     SysFreeString(attr1);
2610 }
2611
2612 static void test_attr_collection_disp(IDispatch *disp)
2613 {
2614     IDispatchEx *dispex;
2615     IHTMLDOMAttribute *attr;
2616     DISPPARAMS dp = {NULL, NULL, 0, 0};
2617     VARIANT var;
2618     EXCEPINFO ei;
2619     DISPID id;
2620     BSTR bstr;
2621     HRESULT hres;
2622
2623     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2624     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2625
2626     bstr = a2bstr("0");
2627     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
2628     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2629     SysFreeString(bstr);
2630
2631     VariantInit(&var);
2632     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2633     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2634     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2635     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
2636     VariantClear(&var);
2637
2638     bstr = a2bstr("attr1");
2639     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
2640     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2641     SysFreeString(bstr);
2642
2643     VariantInit(&var);
2644     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2645     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2646     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2647     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
2648     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLDOMAttribute, (void**)&attr);
2649     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2650     hres = IHTMLDOMAttribute_get_nodeName(attr, &bstr);
2651     ok(hres == S_OK, "get_nodeName failed: %08x\n", hres);
2652     ok(!strcmp_wa(bstr, "attr1"), "node name is %s, expected attr1\n", wine_dbgstr_w(bstr));
2653     SysFreeString(bstr);
2654     IHTMLDOMAttribute_Release(attr);
2655     VariantClear(&var);
2656
2657     IDispatchEx_Release(dispex);
2658 }
2659
2660 static void test_attr_collection(IHTMLElement *elem)
2661 {
2662     static const WCHAR testW[] = {'t','e','s','t',0};
2663
2664     IHTMLDOMNode *node;
2665     IDispatch *disp, *attr;
2666     IHTMLDOMAttribute *dom_attr;
2667     IHTMLAttributeCollection *attr_col;
2668     BSTR name = SysAllocString(testW);
2669     VARIANT id, val;
2670     LONG i, len, checked;
2671     HRESULT hres;
2672
2673     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLDOMNode, (void**)&node);
2674     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2675
2676     hres = IHTMLDOMNode_get_attributes(node, &disp);
2677     ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
2678
2679     hres = IHTMLDOMNode_get_attributes(node, &attr);
2680     ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
2681     ok(iface_cmp((IUnknown*)disp, (IUnknown*)attr), "disp != attr\n");
2682     IDispatch_Release(attr);
2683     IHTMLDOMNode_Release(node);
2684
2685     hres = IDispatch_QueryInterface(disp, &IID_IHTMLAttributeCollection, (void**)&attr_col);
2686     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
2687
2688     hres = IHTMLAttributeCollection_get_length(attr_col, &i);
2689     ok(hres == S_OK, "get_length failed: %08x\n", hres);
2690
2691     V_VT(&val) = VT_I4;
2692     V_I4(&val) = 1;
2693     hres = IHTMLElement_setAttribute(elem, name, val, 0);
2694     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
2695     SysFreeString(name);
2696
2697     hres = IHTMLAttributeCollection_get_length(attr_col, &len);
2698     ok(hres == S_OK, "get_length failed: %08x\n", hres);
2699     ok(len == i+1, "get_length returned %d, expected %d\n", len, i+1);
2700
2701     checked = 0;
2702     for(i=0; i<len; i++) {
2703         V_VT(&id) = VT_I4;
2704         V_I4(&id) = i;
2705         hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
2706         ok(hres == S_OK, "%d) item failed: %08x\n", i, hres);
2707
2708         hres = IDispatch_QueryInterface(attr, &IID_IHTMLDOMAttribute, (void**)&dom_attr);
2709         ok(hres == S_OK, "%d) QueryInterface failed: %08x\n", i, hres);
2710         IDispatch_Release(attr);
2711
2712         hres = IHTMLDOMAttribute_get_nodeName(dom_attr, &name);
2713         ok(hres == S_OK, "%d) get_nodeName failed: %08x\n", i, hres);
2714
2715         if(!strcmp_wa(name, "id")) {
2716             checked++;
2717             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2718             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2719             ok(V_VT(&val) == VT_BSTR, "id: V_VT(&val) = %d\n", V_VT(&val));
2720             ok(!strcmp_wa(V_BSTR(&val), "attr"), "id: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
2721         } else if(!strcmp_wa(name, "attr1")) {
2722             checked++;
2723             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2724             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2725             ok(V_VT(&val) == VT_BSTR, "attr1: V_VT(&val) = %d\n", V_VT(&val));
2726             ok(!strcmp_wa(V_BSTR(&val), "attr1"), "attr1: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
2727         } else if(!strcmp_wa(name, "attr2")) {
2728             checked++;
2729             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2730             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2731             ok(V_VT(&val) == VT_BSTR, "attr2: V_VT(&val) = %d\n", V_VT(&val));
2732             ok(!V_BSTR(&val), "attr2: V_BSTR(&val) != NULL\n");
2733         } else if(!strcmp_wa(name, "attr3")) {
2734             checked++;
2735             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2736             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2737             ok(V_VT(&val) == VT_BSTR, "attr3: V_VT(&val) = %d\n", V_VT(&val));
2738             ok(!strcmp_wa(V_BSTR(&val), "attr3"), "attr3: V_BSTR(&val) = %s\n", wine_dbgstr_w(V_BSTR(&val)));
2739         } else if(!strcmp_wa(name, "test")) {
2740             checked++;
2741             hres = IHTMLDOMAttribute_get_nodeValue(dom_attr, &val);
2742             ok(hres == S_OK, "%d) get_nodeValue failed: %08x\n", i, hres);
2743             ok(V_VT(&val) == VT_I4, "test: V_VT(&val) = %d\n", V_VT(&val));
2744             ok(V_I4(&val) == 1, "test: V_I4(&val) = %d\n", V_I4(&val));
2745         }
2746
2747         IHTMLDOMAttribute_Release(dom_attr);
2748         SysFreeString(name);
2749         VariantClear(&val);
2750     }
2751     ok(checked==5, "invalid number of specified attributes (%d)\n", checked);
2752
2753     V_I4(&id) = len;
2754     hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
2755     ok(hres == E_INVALIDARG, "item failed: %08x\n", hres);
2756
2757     V_VT(&id) = VT_BSTR;
2758     V_BSTR(&id) = a2bstr("nonexisting");
2759     hres = IHTMLAttributeCollection_item(attr_col, &id, &attr);
2760     ok(hres == E_INVALIDARG, "item failed: %08x\n", hres);
2761     VariantClear(&id);
2762
2763     test_attr_collection_disp(disp);
2764
2765     IDispatch_Release(disp);
2766     IHTMLAttributeCollection_Release(attr_col);
2767 }
2768
2769 #define test_attr_specified(a,b) _test_attr_specified(__LINE__,a,b)
2770 static void _test_attr_specified(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected)
2771 {
2772     VARIANT_BOOL specified;
2773     HRESULT hres;
2774
2775     hres = IHTMLDOMAttribute_get_specified(attr, &specified);
2776     ok_(__FILE__,line)(hres == S_OK, "get_specified failed: %08x\n", hres);
2777     ok_(__FILE__,line)(specified == expected, "specified = %x, expected %x\n", specified, expected);
2778 }
2779
2780 #define test_input_type(i,t) _test_input_type(__LINE__,i,t)
2781 static void _test_input_type(unsigned line, IHTMLInputElement *input, const char *extype)
2782 {
2783     BSTR type;
2784     HRESULT hres;
2785
2786     hres = IHTMLInputElement_get_type(input, &type);
2787     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
2788     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
2789     SysFreeString(type);
2790 }
2791
2792 #define test_input_name(u, c) _test_input_name(__LINE__,u, c)
2793 static void _test_input_name(unsigned line, IHTMLInputElement *input, const char *exname)
2794 {
2795     BSTR name = (BSTR)0xdeadbeef;
2796     HRESULT hres;
2797
2798     hres = IHTMLInputElement_get_name(input, &name);
2799     ok_(__FILE__,line) (hres == S_OK, "get_name failed: %08x\n", hres);
2800     if(exname)
2801         ok_(__FILE__,line) (!strcmp_wa (name, exname), "name=%s, expected %s\n", wine_dbgstr_w(name), exname);
2802     else
2803         ok_(__FILE__,line) (!name, "name=%p, expected NULL\n", name);
2804     SysFreeString(name);
2805 }
2806
2807 #define test_input_set_name(u, c) _test_input_set_name(__LINE__,u, c)
2808 static void _test_input_set_name(unsigned line, IHTMLInputElement *input, const char *name)
2809 {
2810     BSTR tmp = a2bstr(name);
2811     HRESULT hres;
2812
2813     hres = IHTMLInputElement_put_name(input, tmp);
2814     ok_(__FILE__,line) (hres == S_OK, "put_name failed: %08x\n", hres);
2815     SysFreeString(tmp);
2816
2817     _test_input_name(line, input, name);
2818 }
2819
2820 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
2821 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2822 {
2823     VARIANT_BOOL disabled = 100;
2824     HRESULT hres;
2825
2826     hres = IHTMLInputElement_get_disabled(input, &disabled);
2827     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2828     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
2829
2830     _test_elem3_get_disabled(line, (IUnknown*)input, exb);
2831 }
2832
2833 #define test_input_set_disabled(i,b) _test_input_set_disabled(__LINE__,i,b)
2834 static void _test_input_set_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2835 {
2836     HRESULT hres;
2837
2838     hres = IHTMLInputElement_put_disabled(input, b);
2839     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
2840
2841     _test_input_get_disabled(line, input, b);
2842 }
2843
2844 #define test_input_get_defaultchecked(i,b) _test_input_get_defaultchecked(__LINE__,i,b)
2845 static void _test_input_get_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2846 {
2847     VARIANT_BOOL checked = 100;
2848     HRESULT hres;
2849
2850     hres = IHTMLInputElement_get_defaultChecked(input, &checked);
2851     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
2852     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
2853 }
2854
2855 #define test_input_set_defaultchecked(i,b) _test_input_set_defaultchecked(__LINE__,i,b)
2856 static void _test_input_set_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2857 {
2858     HRESULT hres;
2859
2860     hres = IHTMLInputElement_put_defaultChecked(input, b);
2861     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
2862
2863     _test_input_get_defaultchecked(line, input, b);
2864 }
2865
2866 #define test_input_get_checked(i,b) _test_input_get_checked(__LINE__,i,b)
2867 static void _test_input_get_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2868 {
2869     VARIANT_BOOL checked = 100;
2870     HRESULT hres;
2871
2872     hres = IHTMLInputElement_get_checked(input, &checked);
2873     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
2874     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
2875 }
2876
2877 #define test_input_set_checked(i,b) _test_input_set_checked(__LINE__,i,b)
2878 static void _test_input_set_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2879 {
2880     HRESULT hres;
2881
2882     hres = IHTMLInputElement_put_checked(input, b);
2883     ok_(__FILE__,line) (hres == S_OK, "put_checked failed: %08x\n", hres);
2884
2885     _test_input_get_checked(line, input, b);
2886 }
2887
2888 #define test_input_maxlength(i,b) _test_input_maxlength(__LINE__,i,b)
2889 static void _test_input_maxlength(unsigned line, IHTMLInputElement *input, LONG exl)
2890 {
2891     LONG maxlength = 0xdeadbeef;
2892     HRESULT hres;
2893
2894     hres = IHTMLInputElement_get_maxLength(input, &maxlength);
2895     ok_(__FILE__,line) (hres == S_OK, "get_maxLength failed: %08x\n", hres);
2896     ok_(__FILE__,line) (maxlength == exl, "maxLength=%x, expected %d\n", maxlength, exl);
2897 }
2898
2899 #define test_input_set_maxlength(i,b) _test_input_set_maxlength(__LINE__,i,b)
2900 static void _test_input_set_maxlength(unsigned line, IHTMLInputElement *input, LONG l)
2901 {
2902     HRESULT hres;
2903
2904     hres = IHTMLInputElement_put_maxLength(input, l);
2905     ok_(__FILE__,line) (hres == S_OK, "put_maxLength failed: %08x\n", hres);
2906
2907     _test_input_maxlength(line, input, l);
2908 }
2909
2910 #define test_input_value(o,t) _test_input_value(__LINE__,o,t)
2911 static void _test_input_value(unsigned line, IUnknown *unk, const char *exval)
2912 {
2913     IHTMLInputElement *input;
2914     BSTR bstr;
2915     HRESULT hres;
2916
2917     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
2918     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
2919     if(FAILED(hres))
2920         return;
2921
2922     hres = IHTMLInputElement_get_value(input, &bstr);
2923     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
2924     if(exval)
2925         ok_(__FILE__,line) (!strcmp_wa(bstr, exval), "value=%s\n", wine_dbgstr_w(bstr));
2926     else
2927         ok_(__FILE__,line) (!bstr, "exval != NULL\n");
2928     SysFreeString(bstr);
2929     IHTMLInputElement_Release(input);
2930 }
2931
2932 #define test_input_put_value(o,v) _test_input_put_value(__LINE__,o,v)
2933 static void _test_input_put_value(unsigned line, IUnknown *unk, const char *val)
2934 {
2935     IHTMLInputElement *input;
2936     BSTR bstr;
2937     HRESULT hres;
2938
2939     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
2940     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
2941     if(FAILED(hres))
2942         return;
2943
2944     bstr = a2bstr(val);
2945     hres = IHTMLInputElement_put_value(input, bstr);
2946     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
2947     SysFreeString(bstr);
2948     IHTMLInputElement_Release(input);
2949
2950     _test_input_value(line, unk, val);
2951 }
2952
2953 #define test_input_defaultValue(o,t) _test_input_defaultValue(__LINE__,o,t)
2954 static void _test_input_defaultValue(unsigned line, IUnknown *unk, const char *exval)
2955 {
2956     IHTMLInputElement *input;
2957     BSTR str;
2958     HRESULT hres;
2959
2960     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
2961     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
2962     if(FAILED(hres))
2963         return;
2964
2965     hres = IHTMLInputElement_get_defaultValue(input, &str);
2966     ok_(__FILE__,line) (hres == S_OK, "get_defaultValue failed: %08x\n", hres);
2967     if(exval)
2968         ok_(__FILE__,line) (!strcmp_wa(str, exval), "defaultValue=%s\n", wine_dbgstr_w(str));
2969     else
2970         ok_(__FILE__,line) (!str, "exval != NULL\n");
2971     SysFreeString(str);
2972     IHTMLInputElement_Release(input);
2973 }
2974
2975 #define test_input_put_defaultValue(o,v) _test_input_put_defaultValue(__LINE__,o,v)
2976 static void _test_input_put_defaultValue(unsigned line, IUnknown *unk, const char *val)
2977 {
2978     IHTMLInputElement *input;
2979     BSTR str;
2980     HRESULT hres;
2981
2982     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
2983     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
2984     if(FAILED(hres))
2985         return;
2986
2987     str = a2bstr(val);
2988     hres = IHTMLInputElement_put_defaultValue(input, str);
2989     ok_(__FILE__,line) (hres == S_OK, "get_defaultValue failed: %08x\n", hres);
2990     SysFreeString(str);
2991     IHTMLInputElement_Release(input);
2992
2993     _test_input_defaultValue(line, unk, val);
2994 }
2995
2996 #define test_input_src(i,s) _test_input_src(__LINE__,i,s)
2997 static void _test_input_src(unsigned line, IHTMLInputElement *input, const char *exsrc)
2998 {
2999     BSTR src;
3000     HRESULT hres;
3001
3002     hres = IHTMLInputElement_get_src(input, &src);
3003     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
3004     if(exsrc)
3005         ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
3006     else
3007         ok_(__FILE__,line) (!src, "get_src returned %s expected NULL\n", wine_dbgstr_w(src));
3008     SysFreeString(src);
3009 }
3010
3011 #define test_input_set_src(u,s) _test_input_set_src(__LINE__,u,s)
3012 static void _test_input_set_src(unsigned line, IHTMLInputElement *input, const char *src)
3013 {
3014     BSTR tmp;
3015     HRESULT hres;
3016
3017     tmp = a2bstr(src);
3018     hres = IHTMLInputElement_put_src(input, tmp);
3019     SysFreeString(tmp);
3020     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
3021
3022     _test_input_src(line, input, src);
3023 }
3024
3025 #define test_elem_class(u,c) _test_elem_class(__LINE__,u,c)
3026 static void _test_elem_class(unsigned line, IUnknown *unk, const char *exclass)
3027 {
3028     IHTMLElement *elem = _get_elem_iface(line, unk);
3029     BSTR class = (void*)0xdeadbeef;
3030     HRESULT hres;
3031
3032     hres = IHTMLElement_get_className(elem, &class);
3033     IHTMLElement_Release(elem);
3034     ok_(__FILE__,line) (hres == S_OK, "get_className failed: %08x\n", hres);
3035     if(exclass)
3036         ok_(__FILE__,line) (!strcmp_wa(class, exclass), "unexpected className %s\n", wine_dbgstr_w(class));
3037     else
3038         ok_(__FILE__,line) (!class, "class != NULL\n");
3039     SysFreeString(class);
3040 }
3041
3042 #define test_elem_tabindex(u,i) _test_elem_tabindex(__LINE__,u,i)
3043 static void _test_elem_tabindex(unsigned line, IUnknown *unk, short exindex)
3044 {
3045     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
3046     short index = -3;
3047     HRESULT hres;
3048
3049     hres = IHTMLElement2_get_tabIndex(elem2, &index);
3050     IHTMLElement2_Release(elem2);
3051     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
3052     ok_(__FILE__,line) (index == exindex, "unexpected index %d\n", index);
3053 }
3054
3055 #define test_elem_set_tabindex(u,i) _test_elem_set_tabindex(__LINE__,u,i)
3056 static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index)
3057 {
3058     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
3059     HRESULT hres;
3060
3061     hres = IHTMLElement2_put_tabIndex(elem2, index);
3062     IHTMLElement2_Release(elem2);
3063     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
3064
3065     _test_elem_tabindex(line, unk, index);
3066 }
3067
3068 #define test_style_media(s,m) _test_style_media(__LINE__,s,m)
3069 static void _test_style_media(unsigned line, IUnknown *unk, const char *exmedia)
3070 {
3071     IHTMLStyleElement *style = _get_style_iface(line, unk);
3072     BSTR media;
3073     HRESULT hres;
3074
3075     hres = IHTMLStyleElement_get_media(style, &media);
3076     ok_(__FILE__,line)(hres == S_OK, "get_media failed: %08x\n", hres);
3077     if(exmedia)
3078         ok_(__FILE__,line)(!strcmp_wa(media, exmedia), "media = %s, expected %s\n", wine_dbgstr_w(media), exmedia);
3079     else
3080         ok_(__FILE__,line)(!media, "media = %s, expected NULL\n", wine_dbgstr_w(media));
3081
3082     IHTMLStyleElement_Release(style);
3083     SysFreeString(media);
3084 }
3085
3086 #define test_style_put_media(s,m) _test_style_put_media(__LINE__,s,m)
3087 static void _test_style_put_media(unsigned line, IUnknown *unk, const char *media)
3088 {
3089     IHTMLStyleElement *style = _get_style_iface(line, unk);
3090     BSTR str;
3091     HRESULT hres;
3092
3093     str = a2bstr(media);
3094     hres = IHTMLStyleElement_put_media(style, str);
3095     ok_(__FILE__,line)(hres == S_OK, "put_media failed: %08x\n", hres);
3096     IHTMLStyleElement_Release(style);
3097     SysFreeString(str);
3098
3099     _test_style_media(line, unk, media);
3100 }
3101
3102 #define test_style_type(s,m) _test_style_type(__LINE__,s,m)
3103 static void _test_style_type(unsigned line, IUnknown *unk, const char *extype)
3104 {
3105     IHTMLStyleElement *style = _get_style_iface(line, unk);
3106     BSTR type;
3107     HRESULT hres;
3108
3109     hres = IHTMLStyleElement_get_type(style, &type);
3110     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
3111     if(extype)
3112         ok_(__FILE__,line)(!strcmp_wa(type, extype), "type = %s, expected %s\n", wine_dbgstr_w(type), extype);
3113     else
3114         ok_(__FILE__,line)(!type, "type = %s, expected NULL\n", wine_dbgstr_w(type));
3115
3116     IHTMLStyleElement_Release(style);
3117     SysFreeString(type);
3118 }
3119
3120 #define test_style_put_type(s,m) _test_style_put_type(__LINE__,s,m)
3121 static void _test_style_put_type(unsigned line, IUnknown *unk, const char *type)
3122 {
3123     IHTMLStyleElement *style = _get_style_iface(line, unk);
3124     BSTR str;
3125     HRESULT hres;
3126
3127     str = a2bstr(type);
3128     hres = IHTMLStyleElement_put_type(style, str);
3129     ok_(__FILE__,line)(hres == S_OK, "put_type failed: %08x\n", hres);
3130     IHTMLStyleElement_Release(style);
3131     SysFreeString(str);
3132
3133     _test_style_type(line, unk, type);
3134 }
3135
3136 #define test_elem_filters(u) _test_elem_filters(__LINE__,u)
3137 static void _test_elem_filters(unsigned line, IUnknown *unk)
3138 {
3139     IHTMLElement *elem = _get_elem_iface(line, unk);
3140     HRESULT hres;
3141     IHTMLFiltersCollection *filters;
3142
3143     hres = IHTMLElement_get_filters(elem, &filters);
3144     ok_(__FILE__,line) (hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG) /* NT4 */,
3145                         "get_filters failed: %08x\n", hres);
3146     if(hres == S_OK)
3147     {
3148         LONG len;
3149         IDispatchEx *dispex;
3150
3151         hres = IHTMLFiltersCollection_get_length(filters, &len);
3152         ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
3153         ok_(__FILE__,line) (len == 0, "expect 0 got %d\n", len);
3154
3155         hres = IHTMLFiltersCollection_QueryInterface(filters, &IID_IDispatchEx, (void**)&dispex);
3156         ok_(__FILE__,line) (hres == S_OK || broken(hres == E_NOINTERFACE),
3157                             "Could not get IDispatchEx interface: %08x\n", hres);
3158         if(SUCCEEDED(hres)) {
3159             test_disp((IUnknown*)filters, &IID_IHTMLFiltersCollection, "[object]");
3160             IDispatchEx_Release(dispex);
3161         }
3162
3163         IHTMLFiltersCollection_Release(filters);
3164     }
3165
3166     IHTMLElement_Release(elem);
3167 }
3168
3169 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
3170 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
3171 {
3172     IHTMLElement *elem = _get_elem_iface(line, unk);
3173     BSTR tmp;
3174     HRESULT hres;
3175
3176     tmp = class ? a2bstr(class) : NULL;
3177     hres = IHTMLElement_put_className(elem, tmp);
3178     IHTMLElement_Release(elem);
3179     ok_(__FILE__,line) (hres == S_OK, "put_className failed: %08x\n", hres);
3180     SysFreeString(tmp);
3181
3182     _test_elem_class(line, unk, class);
3183 }
3184
3185 #define test_elem_id(e,i) _test_elem_id(__LINE__,e,i)
3186 static void _test_elem_id(unsigned line, IUnknown *unk, const char *exid)
3187 {
3188     IHTMLElement *elem = _get_elem_iface(line, unk);
3189     BSTR id = (void*)0xdeadbeef;
3190     HRESULT hres;
3191
3192     hres = IHTMLElement_get_id(elem, &id);
3193     IHTMLElement_Release(elem);
3194     ok_(__FILE__,line) (hres == S_OK, "get_id failed: %08x\n", hres);
3195
3196     if(exid)
3197         ok_(__FILE__,line) (!strcmp_wa(id, exid), "unexpected id %s\n", wine_dbgstr_w(id));
3198     else
3199         ok_(__FILE__,line) (!id, "id=%s\n", wine_dbgstr_w(id));
3200
3201     SysFreeString(id);
3202 }
3203
3204 #define test_elem_put_id(u,i) _test_elem_put_id(__LINE__,u,i)
3205 static void _test_elem_put_id(unsigned line, IUnknown *unk, const char *new_id)
3206 {
3207     IHTMLElement *elem = _get_elem_iface(line, unk);
3208     BSTR tmp = a2bstr(new_id);
3209     HRESULT hres;
3210
3211     hres = IHTMLElement_put_id(elem, tmp);
3212     IHTMLElement_Release(elem);
3213     SysFreeString(tmp);
3214     ok_(__FILE__,line) (hres == S_OK, "put_id failed: %08x\n", hres);
3215
3216     _test_elem_id(line, unk, new_id);
3217 }
3218
3219 #define test_elem_title(u,t) _test_elem_title(__LINE__,u,t)
3220 static void _test_elem_title(unsigned line, IUnknown *unk, const char *extitle)
3221 {
3222     IHTMLElement *elem = _get_elem_iface(line, unk);
3223     BSTR title;
3224     HRESULT hres;
3225
3226     hres = IHTMLElement_get_title(elem, &title);
3227     IHTMLElement_Release(elem);
3228     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3229     if(extitle)
3230         ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
3231     else
3232         ok_(__FILE__,line) (!title, "title=%s, expected NULL\n", wine_dbgstr_w(title));
3233
3234     SysFreeString(title);
3235 }
3236
3237 #define test_elem_set_title(u,t) _test_elem_set_title(__LINE__,u,t)
3238 static void _test_elem_set_title(unsigned line, IUnknown *unk, const char *title)
3239 {
3240     IHTMLElement *elem = _get_elem_iface(line, unk);
3241     BSTR tmp;
3242     HRESULT hres;
3243
3244     tmp = a2bstr(title);
3245     hres = IHTMLElement_put_title(elem, tmp);
3246     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3247
3248     IHTMLElement_Release(elem);
3249     SysFreeString(tmp);
3250 }
3251
3252 #define test_node_get_value_str(u,e) _test_node_get_value_str(__LINE__,u,e)
3253 static void _test_node_get_value_str(unsigned line, IUnknown *unk, const char *exval)
3254 {
3255     IHTMLDOMNode *node = _get_node_iface(line, unk);
3256     VARIANT var;
3257     HRESULT hres;
3258
3259     hres = IHTMLDOMNode_get_nodeValue(node, &var);
3260     IHTMLDOMNode_Release(node);
3261     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
3262
3263     if(exval) {
3264         ok_(__FILE__,line) (V_VT(&var) == VT_BSTR, "vt=%d\n", V_VT(&var));
3265         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&var), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&var)));
3266     }else {
3267         ok_(__FILE__,line) (V_VT(&var) == VT_NULL, "vt=%d, expected VT_NULL\n", V_VT(&var));
3268     }
3269
3270     VariantClear(&var);
3271 }
3272
3273 #define test_node_put_value_str(u,v) _test_node_put_value_str(__LINE__,u,v)
3274 static void _test_node_put_value_str(unsigned line, IUnknown *unk, const char *val)
3275 {
3276     IHTMLDOMNode *node = _get_node_iface(line, unk);
3277     VARIANT var;
3278     HRESULT hres;
3279
3280     V_VT(&var) = VT_BSTR;
3281     V_BSTR(&var) = a2bstr(val);
3282
3283     hres = IHTMLDOMNode_put_nodeValue(node, var);
3284     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
3285     IHTMLDOMNode_Release(node);
3286     VariantClear(&var);
3287 }
3288
3289 #define test_elem_client_size(u) _test_elem_client_size(__LINE__,u)
3290 static void _test_elem_client_size(unsigned line, IUnknown *unk)
3291 {
3292     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3293     LONG l;
3294     HRESULT hres;
3295
3296     hres = IHTMLElement2_get_clientWidth(elem, &l);
3297     ok_(__FILE__,line) (hres == S_OK, "get_clientWidth failed: %08x\n", hres);
3298     hres = IHTMLElement2_get_clientHeight(elem, &l);
3299     ok_(__FILE__,line) (hres == S_OK, "get_clientHeight failed: %08x\n", hres);
3300
3301     IHTMLElement2_Release(elem);
3302 }
3303
3304 #define test_elem_client_rect(u) _test_elem_client_rect(__LINE__,u)
3305 static void _test_elem_client_rect(unsigned line, IUnknown *unk)
3306 {
3307     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
3308     LONG l;
3309     HRESULT hres;
3310
3311     hres = IHTMLElement2_get_clientLeft(elem, &l);
3312     ok_(__FILE__,line) (hres == S_OK, "get_clientLeft failed: %08x\n", hres);
3313     ok_(__FILE__,line) (!l, "clientLeft = %d\n", l);
3314
3315     hres = IHTMLElement2_get_clientTop(elem, &l);
3316     ok_(__FILE__,line) (hres == S_OK, "get_clientTop failed: %08x\n", hres);
3317     ok_(__FILE__,line) (!l, "clientTop = %d\n", l);
3318
3319     IHTMLElement2_Release(elem);
3320 }
3321
3322 #define test_form_length(e,l) _test_form_length(__LINE__,e,l)
3323 static void _test_form_length(unsigned line, IUnknown *unk, LONG exlen)
3324 {
3325     IHTMLFormElement *form = _get_form_iface(line, unk);
3326     LONG len = 0xdeadbeef;
3327     HRESULT hres;
3328
3329     hres = IHTMLFormElement_get_length(form, &len);
3330     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
3331     ok_(__FILE__,line)(len == exlen, "length=%d, expected %d\n", len, exlen);
3332
3333     IHTMLFormElement_Release(form);
3334 }
3335
3336 #define test_form_action(f,a) _test_form_action(__LINE__,f,a)
3337 static void _test_form_action(unsigned line, IUnknown *unk, const char *ex)
3338 {
3339     IHTMLFormElement *form = _get_form_iface(line, unk);
3340     BSTR action = (void*)0xdeadbeef;
3341     HRESULT hres;
3342
3343     hres = IHTMLFormElement_get_action(form, &action);
3344     ok_(__FILE__,line)(hres == S_OK, "get_action failed: %08x\n", hres);
3345     if(ex)
3346         ok_(__FILE__,line)(!strcmp_wa(action, ex), "action=%s, expected %s\n", wine_dbgstr_w(action), ex);
3347     else
3348         ok_(__FILE__,line)(!action, "action=%p\n", action);
3349
3350     SysFreeString(action);
3351     IHTMLFormElement_Release(form);
3352 }
3353
3354 #define test_form_put_action(f,a) _test_form_put_action(__LINE__,f,a)
3355 static void _test_form_put_action(unsigned line, IUnknown *unk, const char *action)
3356 {
3357     IHTMLFormElement *form = _get_form_iface(line, unk);
3358     BSTR tmp = a2bstr(action);
3359     HRESULT hres;
3360
3361     hres = IHTMLFormElement_put_action(form, tmp);
3362     ok_(__FILE__,line)(hres == S_OK, "put_action failed: %08x\n", hres);
3363     SysFreeString(tmp);
3364     IHTMLFormElement_Release(form);
3365
3366     _test_form_action(line, unk, action);
3367 }
3368
3369 #define test_form_method(f,a) _test_form_method(__LINE__,f,a)
3370 static void _test_form_method(unsigned line, IUnknown *unk, const char *ex)
3371 {
3372     IHTMLFormElement *form = _get_form_iface(line, unk);
3373     BSTR method = (void*)0xdeadbeef;
3374     HRESULT hres;
3375
3376     hres = IHTMLFormElement_get_method(form, &method);
3377     ok_(__FILE__,line)(hres == S_OK, "get_method failed: %08x\n", hres);
3378     if(ex)
3379         ok_(__FILE__,line)(!strcmp_wa(method, ex), "method=%s, expected %s\n", wine_dbgstr_w(method), ex);
3380     else
3381         ok_(__FILE__,line)(!method, "method=%p\n", method);
3382
3383     SysFreeString(method);
3384     IHTMLFormElement_Release(form);
3385 }
3386
3387 #define test_form_put_method(f,r,a) _test_form_put_method(__LINE__,f,r,a)
3388 static void _test_form_put_method(unsigned line, IUnknown *unk, HRESULT exp_hres, const char *method)
3389 {
3390     IHTMLFormElement *form = _get_form_iface(line, unk);
3391     BSTR tmp = a2bstr(method);
3392     HRESULT hres;
3393
3394     hres = IHTMLFormElement_put_method(form, tmp);
3395     ok_(__FILE__,line)(hres == exp_hres, "put_method returned: %08x, expected %08x\n", hres, exp_hres);
3396     SysFreeString(tmp);
3397     IHTMLFormElement_Release(form);
3398
3399     if(exp_hres == S_OK)
3400         _test_form_method(line, unk, method);
3401 }
3402
3403 #define test_form_name(f,a) _test_form_name(__LINE__,f,a)
3404 static void _test_form_name(unsigned line, IUnknown *unk, const char *ex)
3405 {
3406     IHTMLFormElement *form = _get_form_iface(line, unk);
3407     BSTR name = (void*)0xdeadbeef;
3408     HRESULT hres;
3409
3410     hres = IHTMLFormElement_get_name(form, &name);
3411     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
3412     if(ex)
3413         ok_(__FILE__,line)(!strcmp_wa(name, ex), "name=%s, expected %s\n", wine_dbgstr_w(name), ex);
3414     else
3415         ok_(__FILE__,line)(!name, "name=%p\n", name);
3416
3417     SysFreeString(name);
3418     IHTMLFormElement_Release(form);
3419 }
3420
3421 #define test_form_put_name(f,a) _test_form_put_name(__LINE__,f,a)
3422 static void _test_form_put_name(unsigned line, IUnknown *unk, const char *name)
3423 {
3424     IHTMLFormElement *form = _get_form_iface(line, unk);
3425     BSTR tmp = a2bstr(name);
3426     HRESULT hres;
3427
3428     hres = IHTMLFormElement_put_name(form, tmp);
3429     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
3430     SysFreeString(tmp);
3431     IHTMLFormElement_Release(form);
3432
3433     _test_form_name(line, unk, name);
3434 }
3435
3436 #define test_form_encoding(f,a) _test_form_encoding(__LINE__,f,a)
3437 static void _test_form_encoding(unsigned line, IUnknown *unk, const char *ex)
3438 {
3439     IHTMLFormElement *form = _get_form_iface(line, unk);
3440     BSTR encoding = (void*)0xdeadbeef;
3441     HRESULT hres;
3442
3443     hres = IHTMLFormElement_get_encoding(form, &encoding);
3444     ok_(__FILE__,line)(hres == S_OK, "get_encoding failed: %08x\n", hres);
3445     if(ex)
3446         ok_(__FILE__,line)(!strcmp_wa(encoding, ex), "encoding=%s, expected %s\n", wine_dbgstr_w(encoding), ex);
3447     else
3448         ok_(__FILE__,line)(!encoding, "encoding=%p\n", encoding);
3449
3450     SysFreeString(encoding);
3451     IHTMLFormElement_Release(form);
3452 }
3453
3454 #define test_form_put_encoding(f,r,a) _test_form_put_encoding(__LINE__,f,r,a)
3455 static void _test_form_put_encoding(unsigned line, IUnknown *unk, HRESULT exp_hres, const char *encoding)
3456 {
3457     IHTMLFormElement *form = _get_form_iface(line, unk);
3458     BSTR tmp = a2bstr(encoding);
3459     HRESULT hres;
3460
3461     hres = IHTMLFormElement_put_encoding(form, tmp);
3462     ok_(__FILE__,line)(hres == exp_hres, "put_encoding returned: %08x, expected %08x\n", hres, exp_hres);
3463     SysFreeString(tmp);
3464     IHTMLFormElement_Release(form);
3465
3466     if(exp_hres == S_OK)
3467         _test_form_encoding(line, unk, encoding);
3468 }
3469
3470 #define test_form_elements(a) _test_form_elements(__LINE__,a)
3471 static void _test_form_elements(unsigned line, IUnknown *unk)
3472 {
3473     IHTMLFormElement *form = _get_form_iface(line, unk);
3474     IDispatch *disp;
3475     HRESULT hres;
3476
3477     disp = NULL;
3478     hres = IHTMLFormElement_get_elements(form, &disp);
3479     ok_(__FILE__,line)(hres == S_OK, "get_elements failed: %08x\n", hres);
3480     ok_(__FILE__,line)(disp != NULL, "disp = NULL\n");
3481     ok_(__FILE__,line)(iface_cmp((IUnknown*)form, (IUnknown*)disp), "disp != form\n");
3482
3483     IDispatch_Release(disp);
3484     IHTMLFormElement_Release(form);
3485 }
3486
3487 #define test_meta_name(a,b) _test_meta_name(__LINE__,a,b)
3488 static void _test_meta_name(unsigned line, IUnknown *unk, const char *exname)
3489 {
3490     IHTMLMetaElement *meta;
3491     BSTR name = NULL;
3492     HRESULT hres;
3493
3494
3495     meta = _get_metaelem_iface(line, unk);
3496     hres = IHTMLMetaElement_get_name(meta, &name);
3497     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
3498     ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s, expected %s\n", wine_dbgstr_w(name), exname);
3499     SysFreeString(name);
3500     IHTMLMetaElement_Release(meta);
3501 }
3502
3503 #define test_meta_content(a,b) _test_meta_content(__LINE__,a,b)
3504 static void _test_meta_content(unsigned line, IUnknown *unk, const char *excontent)
3505 {
3506     IHTMLMetaElement *meta;
3507     BSTR content = NULL;
3508     HRESULT hres;
3509
3510
3511     meta = _get_metaelem_iface(line, unk);
3512     hres = IHTMLMetaElement_get_content(meta, &content);
3513     ok_(__FILE__,line)(hres == S_OK, "get_content failed: %08x\n", hres);
3514     ok_(__FILE__,line)(!strcmp_wa(content, excontent), "content = %s, expected %s\n", wine_dbgstr_w(content), excontent);
3515     SysFreeString(content);
3516     IHTMLMetaElement_Release(meta);
3517 }
3518
3519 #define test_meta_httpequiv(a,b) _test_meta_httpequiv(__LINE__,a,b)
3520 static void _test_meta_httpequiv(unsigned line, IUnknown *unk, const char *exval)
3521 {
3522     IHTMLMetaElement *meta;
3523     BSTR val = NULL;
3524     HRESULT hres;
3525
3526
3527     meta = _get_metaelem_iface(line, unk);
3528     hres = IHTMLMetaElement_get_httpEquiv(meta, &val);
3529     ok_(__FILE__,line)(hres == S_OK, "get_httpEquiv failed: %08x\n", hres);
3530     ok_(__FILE__,line)(!strcmp_wa(val, exval), "httpEquiv = %s, expected %s\n", wine_dbgstr_w(val), exval);
3531     SysFreeString(val);
3532     IHTMLMetaElement_Release(meta);
3533 }
3534
3535 #define test_link_disabled(a,b) _test_link_disabled(__LINE__,a,b)
3536 static void _test_link_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL v)
3537 {
3538     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3539     VARIANT_BOOL b = 10;
3540     HRESULT hres;
3541
3542     hres = IHTMLLinkElement_get_disabled(link, &b);
3543     ok_(__FILE__,line)(hres == S_OK, "get_disabled failed: %08x\n", hres);
3544     ok_(__FILE__,line)(b == v, "disabled = %x, expected %x\n", b, v);
3545
3546     IHTMLLinkElement_Release(link);
3547 }
3548
3549 #define link_put_disabled(a,b) _link_put_disabled(__LINE__,a,b)
3550 static void _link_put_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL v)
3551 {
3552     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3553     HRESULT hres;
3554
3555     hres = IHTMLLinkElement_put_disabled(link, v);
3556     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3557     IHTMLLinkElement_Release(link);
3558     _test_link_disabled(line, elem, v);
3559 }
3560
3561 #define test_link_rel(a,b) _test_link_rel(__LINE__,a,b)
3562 static void _test_link_rel(unsigned line, IHTMLElement *elem, const char *v)
3563 {
3564     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3565     BSTR rel;
3566     HRESULT hres;
3567
3568     hres = IHTMLLinkElement_get_rel(link, &rel);
3569     ok_(__FILE__,line)(hres == S_OK, "get_rel failed: %08x\n", hres);
3570     if(v)
3571         ok_(__FILE__,line)(!strcmp_wa(rel, v), "rel = %s, expected %s\n", wine_dbgstr_w(rel), v);
3572     else
3573         ok_(__FILE__,line)(!rel, "rel = %s, expected NULL\n", wine_dbgstr_w(rel));
3574
3575     IHTMLLinkElement_Release(link);
3576 }
3577
3578 #define link_put_rel(a,b) _link_put_rel(__LINE__,a,b)
3579 static void _link_put_rel(unsigned line, IHTMLElement *elem, const char *v)
3580 {
3581     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3582     BSTR str = a2bstr(v);
3583     HRESULT hres;
3584
3585     hres = IHTMLLinkElement_put_rel(link, str);
3586     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3587     SysFreeString(str);
3588     IHTMLLinkElement_Release(link);
3589     _test_link_rel(line, elem, v);
3590 }
3591
3592 #define test_link_type(a,b) _test_link_type(__LINE__,a,b)
3593 static void _test_link_type(unsigned line, IHTMLElement *elem, const char *v)
3594 {
3595     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3596     BSTR type;
3597     HRESULT hres;
3598
3599     hres = IHTMLLinkElement_get_type(link, &type);
3600     ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres);
3601     if(v)
3602         ok_(__FILE__,line)(!strcmp_wa(type, v), "type = %s, expected %s\n", wine_dbgstr_w(type), v);
3603     else
3604         ok_(__FILE__,line)(!type, "type = %s, expected NULL\n", wine_dbgstr_w(type));
3605
3606     IHTMLLinkElement_Release(link);
3607 }
3608
3609 #define test_script_text(a,b) _test_script_text(__LINE__,a,b)
3610 static void _test_script_text(unsigned line, IHTMLScriptElement *script, const char *extext)
3611 {
3612     BSTR str;
3613     HRESULT hres;
3614
3615     str = (void*)0xdeadbeef;
3616     hres = IHTMLScriptElement_get_text(script, &str);
3617     ok_(__FILE__,line)(hres == S_OK, "get_text failed: %08x\n", hres);
3618     ok(!strcmp_wa(str, extext), "text = %s, expected \"%s\"\n", wine_dbgstr_w(str), extext);
3619     SysFreeString(str);
3620 }
3621
3622 #define link_put_type(a,b) _link_put_type(__LINE__,a,b)
3623 static void _link_put_type(unsigned line, IHTMLElement *elem, const char *v)
3624 {
3625     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3626     BSTR str = a2bstr(v);
3627     HRESULT hres;
3628
3629     hres = IHTMLLinkElement_put_type(link, str);
3630     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3631     SysFreeString(str);
3632     IHTMLLinkElement_Release(link);
3633     _test_link_type(line, elem, v);
3634 }
3635
3636 #define test_link_href(a,b) _test_link_href(__LINE__,a,b)
3637 static void _test_link_href(unsigned line, IHTMLElement *elem, const char *v)
3638 {
3639     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3640     BSTR href;
3641     HRESULT hres;
3642
3643     hres = IHTMLLinkElement_get_href(link, &href);
3644     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
3645     if(v)
3646         ok_(__FILE__,line)(!strcmp_wa(href, v), "href = %s, expected %s\n", wine_dbgstr_w(href), v);
3647     else
3648         ok_(__FILE__,line)(!href, "href = %s, expected NULL\n", wine_dbgstr_w(href));
3649
3650     IHTMLLinkElement_Release(link);
3651 }
3652
3653 #define link_put_href(a,b) _link_put_href(__LINE__,a,b)
3654 static void _link_put_href(unsigned line, IHTMLElement *elem, const char *v)
3655 {
3656     IHTMLLinkElement *link = _get_link_iface(line, (IUnknown*)elem);
3657     BSTR str = a2bstr(v);
3658     HRESULT hres;
3659
3660     hres = IHTMLLinkElement_put_href(link, str);
3661     ok_(__FILE__,line)(hres == S_OK, "put_disabled failed: %08x\n", hres);
3662     SysFreeString(str);
3663     IHTMLLinkElement_Release(link);
3664     _test_link_href(line, elem, v);
3665 }
3666
3667 #define get_elem_doc(e) _get_elem_doc(__LINE__,e)
3668 static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk)
3669 {
3670     IHTMLElement *elem = _get_elem_iface(line, unk);
3671     IHTMLDocument2 *doc;
3672     IDispatch *disp;
3673     HRESULT hres;
3674
3675     disp = NULL;
3676     hres = IHTMLElement_get_document(elem, &disp);
3677     ok(hres == S_OK, "get_document failed: %08x\n", hres);
3678     ok(disp != NULL, "disp == NULL\n");
3679
3680     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
3681     IDispatch_Release(disp);
3682     ok(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
3683
3684     return doc;
3685 }
3686
3687 #define get_elem_attr_node(a,b,c) _get_elem_attr_node(__LINE__,a,b,c)
3688 static IHTMLDOMAttribute *_get_elem_attr_node(unsigned line, IUnknown *unk, const char *attr_name, BOOL expect_success)
3689 {
3690     IHTMLElement4 *elem = _get_elem4_iface(line, unk);
3691     BSTR str = a2bstr(attr_name);
3692     IHTMLDOMAttribute *attr;
3693     HRESULT hres;
3694
3695     attr = (void*)0xdeadbeef;
3696     hres = IHTMLElement4_getAttributeNode(elem, str, &attr);
3697     ok_(__FILE__,line)(hres == S_OK, "getAttributeNode failed: %08x\n", hres);
3698     if(expect_success)
3699         ok_(__FILE__,line)(attr != NULL, "attr = NULL\n");
3700     else
3701         ok_(__FILE__,line)(!attr, "attr = %p\n", attr);
3702
3703     IHTMLElement4_Release(elem);
3704     SysFreeString(str);
3705     return attr;
3706 }
3707
3708 #define get_attr_node_value(a,b,c) _get_attr_node_value(__LINE__,a,b,c)
3709 static void _get_attr_node_value(unsigned line, IHTMLDOMAttribute *attr, VARIANT *v, VARTYPE vt)
3710 {
3711     HRESULT hres;
3712
3713     hres = IHTMLDOMAttribute_get_nodeValue(attr, v);
3714     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
3715     ok_(__FILE__,line) (V_VT(v) == vt, "vt=%d, expected %d\n", V_VT(v), vt);
3716 }
3717
3718 #define get_window_doc(e) _get_window_doc(__LINE__,e)
3719 static IHTMLDocument2 *_get_window_doc(unsigned line, IHTMLWindow2 *window)
3720 {
3721     IHTMLDocument2 *doc;
3722     HRESULT hres;
3723
3724     doc = NULL;
3725     hres = IHTMLWindow2_get_document(window, &doc);
3726     ok(hres == S_OK, "get_document failed: %08x\n", hres);
3727     ok(doc != NULL, "disp == NULL\n");
3728
3729     return doc;
3730 }
3731
3732 #define doc_get_body(d) _doc_get_body(__LINE__,d)
3733 static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc)
3734 {
3735     IHTMLElement *elem;
3736     HRESULT hres;
3737
3738     hres = IHTMLDocument2_get_body(doc, &elem);
3739     ok_(__FILE__,line)(hres == S_OK, "get_body failed: %08x\n", hres);
3740     ok_(__FILE__,line)(elem != NULL, "body == NULL\n");
3741
3742     return elem;
3743 }
3744
3745 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
3746 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
3747 {
3748     IHTMLElement *elem = NULL;
3749     BSTR tmp;
3750     HRESULT hres;
3751
3752     tmp = a2bstr(tag);
3753     hres = IHTMLDocument2_createElement(doc, tmp, &elem);
3754     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
3755     ok_(__FILE__,line) (elem != NULL, "elem == NULL\n");
3756     SysFreeString(tmp);
3757
3758     return elem;
3759 }
3760
3761 #define test_create_text(d,t) _test_create_text(__LINE__,d,t)
3762 static IHTMLDOMNode *_test_create_text(unsigned line, IHTMLDocument2 *doc, const char *text)
3763 {
3764     IHTMLDocument3 *doc3;
3765     IHTMLDOMNode *node = NULL;
3766     BSTR tmp;
3767     HRESULT hres;
3768
3769     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
3770     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3: %08x\n", hres);
3771
3772     tmp = a2bstr(text);
3773     hres = IHTMLDocument3_createTextNode(doc3, tmp, &node);
3774     IHTMLDocument3_Release(doc3);
3775     SysFreeString(tmp);
3776     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
3777     ok_(__FILE__,line) (node != NULL, "node == NULL\n");
3778
3779     return node;
3780 }
3781
3782 #define test_node_append_child(n,c) _test_node_append_child(__LINE__,n,c)
3783 static IHTMLDOMNode *_test_node_append_child(unsigned line, IUnknown *node_unk, IUnknown *child_unk)
3784 {
3785     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
3786     IHTMLDOMNode *child = _get_node_iface(line, child_unk);
3787     IHTMLDOMNode *new_child = NULL;
3788     HRESULT hres;
3789
3790     hres = IHTMLDOMNode_appendChild(node, child, &new_child);
3791     ok_(__FILE__,line) (hres == S_OK, "appendChild failed: %08x\n", hres);
3792     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
3793     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
3794
3795     IHTMLDOMNode_Release(node);
3796     IHTMLDOMNode_Release(child);
3797
3798     return new_child;
3799 }
3800
3801 #define test_node_insertbefore(n,c,v) _test_node_insertbefore(__LINE__,n,c,v)
3802 static IHTMLDOMNode *_test_node_insertbefore(unsigned line, IUnknown *node_unk, IHTMLDOMNode *child, VARIANT *var)
3803 {
3804     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
3805     IHTMLDOMNode *new_child = NULL;
3806     HRESULT hres;
3807
3808     hres = IHTMLDOMNode_insertBefore(node, child, *var, &new_child);
3809     ok_(__FILE__,line) (hres == S_OK, "insertBefore failed: %08x\n", hres);
3810     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
3811     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
3812
3813     IHTMLDOMNode_Release(node);
3814
3815     return new_child;
3816 }
3817
3818 #define test_node_remove_child(n,c) _test_node_remove_child(__LINE__,n,c)
3819 static void _test_node_remove_child(unsigned line, IUnknown *unk, IHTMLDOMNode *child)
3820 {
3821     IHTMLDOMNode *node = _get_node_iface(line, unk);
3822     IHTMLDOMNode *new_node = NULL;
3823     HRESULT hres;
3824
3825     hres = IHTMLDOMNode_removeChild(node, child, &new_node);
3826     ok_(__FILE__,line) (hres == S_OK, "removeChild failed: %08x\n", hres);
3827     ok_(__FILE__,line) (new_node != NULL, "new_node == NULL\n");
3828     /* TODO ok_(__FILE__,line) (new_node != child, "new_node == child\n"); */
3829
3830     IHTMLDOMNode_Release(node);
3831     IHTMLDOMNode_Release(new_node);
3832 }
3833
3834 #define test_doc_title(d,t) _test_doc_title(__LINE__,d,t)
3835 static void _test_doc_title(unsigned line, IHTMLDocument2 *doc, const char *extitle)
3836 {
3837     BSTR title = NULL;
3838     HRESULT hres;
3839
3840     hres = IHTMLDocument2_get_title(doc, &title);
3841     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3842     ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
3843     SysFreeString(title);
3844 }
3845
3846 #define test_doc_set_title(d,t) _test_doc_set_title(__LINE__,d,t)
3847 static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *title)
3848 {
3849     BSTR tmp;
3850     HRESULT hres;
3851
3852     tmp = a2bstr(title);
3853     hres = IHTMLDocument2_put_title(doc, tmp);
3854     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
3855     SysFreeString(tmp);
3856 }
3857
3858 static void test_elem_bounding_client_rect(IUnknown *unk)
3859 {
3860     IHTMLRect *rect, *rect2;
3861     IHTMLElement2 *elem2;
3862     LONG l;
3863     HRESULT hres;
3864
3865     elem2 = get_elem2_iface(unk);
3866     hres = IHTMLElement2_getBoundingClientRect(elem2, &rect);
3867     ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres);
3868     hres = IHTMLElement2_getBoundingClientRect(elem2, &rect2);
3869     IHTMLElement2_Release(elem2);
3870     ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres);
3871     ok(rect != NULL, "rect == NULL\n");
3872     ok(rect != rect2, "rect == rect2\n");
3873     IHTMLRect_Release(rect2);
3874
3875     test_disp((IUnknown*)rect, &IID_IHTMLRect, "[object]");
3876
3877     l = 0xdeadbeef;
3878     hres = IHTMLRect_get_top(rect, &l);
3879     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3880     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3881
3882     l = 0xdeadbeef;
3883     hres = IHTMLRect_get_left(rect, &l);
3884     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3885     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3886
3887     l = 0xdeadbeef;
3888     hres = IHTMLRect_get_bottom(rect, &l);
3889     ok(hres == S_OK, "get_bottom failed: %08x\n", hres);
3890     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3891
3892     l = 0xdeadbeef;
3893     hres = IHTMLRect_get_right(rect, &l);
3894     ok(hres == S_OK, "get_right failed: %08x\n", hres);
3895     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
3896
3897     IHTMLRect_Release(rect);
3898 }
3899
3900 static void test_elem_col_item(IHTMLElementCollection *col, const char *n,
3901         const elem_type_t *elem_types, LONG len)
3902 {
3903     IDispatch *disp;
3904     VARIANT name, index;
3905     DWORD i;
3906     HRESULT hres;
3907
3908     V_VT(&index) = VT_EMPTY;
3909     V_VT(&name) = VT_BSTR;
3910     V_BSTR(&name) = a2bstr(n);
3911
3912     hres = IHTMLElementCollection_item(col, name, index, &disp);
3913     ok(hres == S_OK, "item failed: %08x\n", hres);
3914
3915     test_elem_collection((IUnknown*)disp, elem_types, len);
3916     IDispatch_Release(disp);
3917
3918     V_VT(&index) = VT_I4;
3919
3920     for(i=0; i<len; i++) {
3921         V_I4(&index) = i;
3922         disp = (void*)0xdeadbeef;
3923         hres = IHTMLElementCollection_item(col, name, index, &disp);
3924         ok(hres == S_OK, "item failed: %08x\n", hres);
3925         ok(disp != NULL, "disp == NULL\n");
3926         if(FAILED(hres) || !disp)
3927             continue;
3928
3929         test_elem_type((IUnknown*)disp, elem_types[i]);
3930
3931         IDispatch_Release(disp);
3932     }
3933
3934     V_I4(&index) = len;
3935     disp = (void*)0xdeadbeef;
3936     hres = IHTMLElementCollection_item(col, name, index, &disp);
3937     ok(hres == S_OK, "item failed: %08x\n", hres);
3938     ok(disp == NULL, "disp != NULL\n");
3939
3940     V_I4(&index) = -1;
3941     disp = (void*)0xdeadbeef;
3942     hres = IHTMLElementCollection_item(col, name, index, &disp);
3943     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
3944     ok(disp == NULL, "disp != NULL\n");
3945
3946     SysFreeString(V_BSTR(&name));
3947 }
3948
3949 static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const char *id, BOOL expect_success)
3950 {
3951     IHTMLElementCollection *col;
3952     IHTMLElement *elem;
3953     IDispatch *disp = (void*)0xdeadbeef;
3954     VARIANT name, index;
3955     HRESULT hres;
3956
3957     hres = IHTMLDocument2_get_all(doc, &col);
3958     ok(hres == S_OK, "get_all failed: %08x\n", hres);
3959     ok(col != NULL, "col == NULL\n");
3960     if(FAILED(hres) || !col)
3961         return NULL;
3962
3963     V_VT(&index) = VT_EMPTY;
3964     V_VT(&name) = VT_BSTR;
3965     V_BSTR(&name) = a2bstr(id);
3966
3967     hres = IHTMLElementCollection_item(col, name, index, &disp);
3968     IHTMLElementCollection_Release(col);
3969     SysFreeString(V_BSTR(&name));
3970     ok(hres == S_OK, "item failed: %08x\n", hres);
3971     if(!expect_success) {
3972         ok(disp == NULL, "disp != NULL\n");
3973         return NULL;
3974     }
3975
3976     ok(disp != NULL, "disp == NULL\n");
3977     if(!disp)
3978         return NULL;
3979
3980     elem = get_elem_iface((IUnknown*)disp);
3981     IDispatch_Release(disp);
3982
3983     return elem;
3984 }
3985
3986 static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const char *id)
3987 {
3988     IHTMLDocument3 *doc3;
3989     IHTMLElement *elem;
3990     BSTR tmp;
3991     HRESULT hres;
3992
3993     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
3994     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
3995
3996     tmp = a2bstr(id);
3997     hres = IHTMLDocument3_getElementById(doc3, tmp, &elem);
3998     SysFreeString(tmp);
3999     ok(hres == S_OK, "getElementById(%s) failed: %08x\n", id, hres);
4000
4001     IHTMLDocument3_Release(doc3);
4002
4003     return elem;
4004 }
4005
4006 static void test_select_elem(IHTMLSelectElement *select)
4007 {
4008     IDispatch *disp, *disp2;
4009     VARIANT name, index;
4010     HRESULT hres;
4011
4012     test_select_type(select, "select-one");
4013     test_select_length(select, 2);
4014     test_select_selidx(select, 0);
4015     test_select_put_selidx(select, 1);
4016
4017     test_select_set_value(select, "val1");
4018     test_select_value(select, "val1");
4019
4020     test_select_get_disabled(select, VARIANT_FALSE);
4021     test_select_set_disabled(select, VARIANT_TRUE);
4022     test_select_set_disabled(select, VARIANT_FALSE);
4023
4024     disp = NULL;
4025     hres = IHTMLSelectElement_get_options(select, &disp);
4026     ok(hres == S_OK, "get_options failed: %08x\n", hres);
4027     ok(disp != NULL, "options == NULL\n");
4028     ok(iface_cmp((IUnknown*)disp, (IUnknown*)select), "disp != select\n");
4029     IDispatch_Release(disp);
4030
4031     V_VT(&index) = VT_EMPTY;
4032     V_VT(&name) = VT_I4;
4033     V_I4(&name) = -1;
4034     disp = (void*)0xdeadbeef;
4035     hres = IHTMLSelectElement_item(select, name, index, &disp);
4036     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4037     ok(!disp, "disp = %p\n", disp);
4038
4039     V_I4(&name) = 2;
4040     disp = (void*)0xdeadbeef;
4041     hres = IHTMLSelectElement_item(select, name, index, &disp);
4042     ok(hres == S_OK, "item failed: %08x\n", hres);
4043     ok(!disp, "disp = %p\n", disp);
4044
4045     V_I4(&name) = 1;
4046     hres = IHTMLSelectElement_item(select, name, index, NULL);
4047     ok(hres == E_POINTER || broken(hres == E_INVALIDARG), "item failed: %08x, expected E_POINTER\n", hres);
4048
4049     disp = NULL;
4050     hres = IHTMLSelectElement_item(select, name, index, &disp);
4051     ok(hres == S_OK, "item failed: %08x\n", hres);
4052     ok(disp != NULL, "disp = NULL\n");
4053     test_disp((IUnknown*)disp, &DIID_DispHTMLOptionElement, NULL);
4054
4055     V_VT(&index) = VT_I4;
4056     V_I4(&index) = 1;
4057     disp2 = NULL;
4058     hres = IHTMLSelectElement_item(select, name, index, &disp2);
4059     ok(hres == S_OK, "item failed: %08x\n", hres);
4060     ok(disp2 != NULL, "disp = NULL\n");
4061     ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
4062     IDispatch_Release(disp2);
4063     IDispatch_Release(disp);
4064 }
4065
4066 static void test_form_item(IHTMLElement *elem)
4067 {
4068     IHTMLFormElement *form = get_form_iface((IUnknown*)elem);
4069     IDispatch *disp, *disp2;
4070     VARIANT name, index;
4071     HRESULT hres;
4072
4073     V_VT(&index) = VT_EMPTY;
4074     V_VT(&name) = VT_I4;
4075     V_I4(&name) = -1;
4076     disp = (void*)0xdeadbeef;
4077     hres = IHTMLFormElement_item(form, name, index, &disp);
4078     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4079     ok(!disp, "disp = %p\n", disp);
4080
4081     V_I4(&name) = 2;
4082     disp = (void*)0xdeadbeef;
4083     hres = IHTMLFormElement_item(form, name, index, &disp);
4084     ok(hres == S_OK, "item failed: %08x\n", hres);
4085     ok(!disp, "disp = %p\n", disp);
4086
4087     V_I4(&name) = 1;
4088     hres = IHTMLFormElement_item(form, name, index, NULL);
4089     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
4090
4091     disp = NULL;
4092     hres = IHTMLFormElement_item(form, name, index, &disp);
4093     ok(hres == S_OK, "item failed: %08x\n", hres);
4094     ok(disp != NULL, "disp = NULL\n");
4095     test_disp((IUnknown*)disp, &DIID_DispHTMLInputElement, NULL);
4096
4097     V_VT(&index) = VT_I4;
4098     V_I4(&index) = 1;
4099     disp2 = NULL;
4100     hres = IHTMLFormElement_item(form, name, index, &disp2);
4101     ok(hres == S_OK, "item failed: %08x\n", hres);
4102     ok(disp2 != NULL, "disp = NULL\n");
4103     ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
4104     IDispatch_Release(disp2);
4105     IDispatch_Release(disp);
4106 }
4107
4108 static void test_create_option_elem(IHTMLDocument2 *doc)
4109 {
4110     IHTMLOptionElement *option;
4111
4112     option = create_option_elem(doc, "test text", "test value");
4113
4114     test_option_put_text(option, "new text");
4115     test_option_put_value(option, "new value");
4116     test_option_put_selected(option, VARIANT_TRUE);
4117     test_option_put_selected(option, VARIANT_FALSE);
4118
4119     IHTMLOptionElement_Release(option);
4120 }
4121
4122 static void test_create_img_elem(IHTMLDocument2 *doc)
4123 {
4124     IHTMLImgElement *img;
4125
4126     img = create_img_elem(doc, 10, 15);
4127
4128     if(img){
4129         test_img_put_width(img, 5);
4130         test_img_put_height(img, 20);
4131
4132         IHTMLImgElement_Release(img);
4133         img = NULL;
4134     }
4135
4136     img = create_img_elem(doc, -1, -1);
4137
4138     if(img){
4139         test_img_put_width(img, 5);
4140         test_img_put_height(img, 20);
4141
4142         IHTMLImgElement_Release(img);
4143     }
4144 }
4145
4146 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
4147 {
4148     IHTMLBodyElement *body;
4149     IHTMLTxtRange *range;
4150     IHTMLElement *elem;
4151     HRESULT hres;
4152
4153     elem = doc_get_body(doc);
4154     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
4155     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
4156     IHTMLElement_Release(elem);
4157
4158     hres = IHTMLBodyElement_createTextRange(body, &range);
4159     IHTMLBodyElement_Release(body);
4160     ok(hres == S_OK, "createTextRange failed: %08x\n", hres);
4161
4162     return range;
4163 }
4164
4165 static void test_txtrange(IHTMLDocument2 *doc)
4166 {
4167     IHTMLTxtRange *body_range, *range, *range2;
4168     IHTMLSelectionObject *selection;
4169     IDispatch *disp_range;
4170     HRESULT hres;
4171
4172     body_range = test_create_body_range(doc);
4173
4174     test_range_text(body_range, "test abc 123\r\nit's text");
4175
4176     hres = IHTMLTxtRange_duplicate(body_range, &range);
4177     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4178
4179     hres = IHTMLTxtRange_duplicate(body_range, &range2);
4180     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4181     test_range_isequal(range, range2, VARIANT_TRUE);
4182
4183     test_range_text(range, "test abc 123\r\nit's text");
4184     test_range_text(body_range, "test abc 123\r\nit's text");
4185
4186     test_range_collapse(range, TRUE);
4187     test_range_isequal(range, range2, VARIANT_FALSE);
4188     test_range_inrange(range, range2, VARIANT_FALSE);
4189     test_range_inrange(range2, range, VARIANT_TRUE);
4190     IHTMLTxtRange_Release(range2);
4191
4192     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
4193     test_range_expand(range, wordW, VARIANT_FALSE, "test ");
4194     test_range_move(range, characterW, 2, 2);
4195     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
4196
4197     test_range_collapse(range, FALSE);
4198     test_range_expand(range, wordW, VARIANT_TRUE, "abc ");
4199
4200     test_range_collapse(range, FALSE);
4201     test_range_expand(range, wordW, VARIANT_TRUE, "123");
4202     test_range_expand(range, wordW, VARIANT_FALSE, "123");
4203     test_range_move(range, characterW, 2, 2);
4204     test_range_expand(range, wordW, VARIANT_TRUE, "123");
4205     test_range_moveend(range, characterW, -5, -5);
4206     test_range_text(range, NULL);
4207     test_range_moveend(range, characterW, 3, 3);
4208     test_range_text(range, "c 1");
4209     test_range_expand(range, texteditW, VARIANT_TRUE, "test abc 123\r\nit's text");
4210     test_range_collapse(range, TRUE);
4211     test_range_move(range, characterW, 4, 4);
4212     test_range_moveend(range, characterW, 1, 1);
4213     test_range_text(range, " ");
4214     test_range_move(range, wordW, 1, 1);
4215     test_range_moveend(range, characterW, 2, 2);
4216     test_range_text(range, "ab");
4217
4218     IHTMLTxtRange_Release(range);
4219
4220     hres = IHTMLTxtRange_duplicate(body_range, &range);
4221     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4222
4223     test_range_text(range, "test abc 123\r\nit's text");
4224     test_range_move(range, characterW, 3, 3);
4225     test_range_moveend(range, characterW, 1, 1);
4226     test_range_text(range, "t");
4227     test_range_moveend(range, characterW, 3, 3);
4228     test_range_text(range, "t ab");
4229     test_range_moveend(range, characterW, -2, -2);
4230     test_range_text(range, "t ");
4231     test_range_move(range, characterW, 6, 6);
4232     test_range_moveend(range, characterW, 3, 3);
4233     test_range_text(range, "123");
4234     test_range_moveend(range, characterW, 2, 2);
4235     test_range_text(range, "123\r\ni");
4236
4237     IHTMLTxtRange_Release(range);
4238
4239     hres = IHTMLTxtRange_duplicate(body_range, &range);
4240     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4241
4242     test_range_move(range, wordW, 1, 1);
4243     test_range_moveend(range, characterW, 2, 2);
4244     test_range_text(range, "ab");
4245
4246     test_range_move(range, characterW, -2, -2);
4247     test_range_moveend(range, characterW, 2, 2);
4248     test_range_text(range, "t ");
4249
4250     test_range_move(range, wordW, 3, 3);
4251     test_range_move(range, wordW, -2, -2);
4252     test_range_moveend(range, characterW, 2, 2);
4253     test_range_text(range, "ab");
4254
4255     test_range_move(range, characterW, -6, -5);
4256     test_range_moveend(range, characterW, -1, 0);
4257     test_range_moveend(range, characterW, -6, 0);
4258     test_range_move(range, characterW, 2, 2);
4259     test_range_moveend(range, characterW, 2, 2);
4260     test_range_text(range, "st");
4261     test_range_moveend(range, characterW, -6, -4);
4262     test_range_moveend(range, characterW, 2, 2);
4263
4264     IHTMLTxtRange_Release(range);
4265
4266     hres = IHTMLTxtRange_duplicate(body_range, &range);
4267     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4268
4269     test_range_move(range, wordW, 2, 2);
4270     test_range_moveend(range, characterW, 2, 2);
4271     test_range_text(range, "12");
4272
4273     test_range_move(range, characterW, 15, 14);
4274     test_range_move(range, characterW, -2, -2);
4275     test_range_moveend(range, characterW, 3, 2);
4276     test_range_text(range, "t");
4277     test_range_moveend(range, characterW, -1, -1);
4278     test_range_text(range, "t");
4279     test_range_expand(range, wordW, VARIANT_TRUE, "text");
4280     test_range_move(range, characterW, -2, -2);
4281     test_range_moveend(range, characterW, 2, 2);
4282     test_range_text(range, "s ");
4283     test_range_move(range, characterW, 100, 7);
4284     test_range_move(range, wordW, 1, 0);
4285     test_range_move(range, characterW, -2, -2);
4286     test_range_moveend(range, characterW, 3, 2);
4287     test_range_text(range, "t");
4288
4289     IHTMLTxtRange_Release(range);
4290
4291     hres = IHTMLTxtRange_duplicate(body_range, &range);
4292     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
4293
4294     test_range_collapse(range, TRUE);
4295     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
4296     test_range_put_text(range, "word");
4297     test_range_text(body_range, "wordabc 123\r\nit's text");
4298     test_range_text(range, NULL);
4299     test_range_moveend(range, characterW, 3, 3);
4300     test_range_text(range, "abc");
4301     test_range_movestart(range, characterW, -2, -2);
4302     test_range_text(range, "rdabc");
4303     test_range_movestart(range, characterW, 3, 3);
4304     test_range_text(range, "bc");
4305     test_range_movestart(range, characterW, 4, 4);
4306     test_range_text(range, NULL);
4307     test_range_movestart(range, characterW, -3, -3);
4308     test_range_text(range, "c 1");
4309     test_range_movestart(range, characterW, -7, -6);
4310     test_range_text(range, "wordabc 1");
4311     test_range_movestart(range, characterW, 100, 22);
4312     test_range_text(range, NULL);
4313
4314     IHTMLTxtRange_Release(range);
4315     IHTMLTxtRange_Release(body_range);
4316
4317     hres = IHTMLDocument2_get_selection(doc, &selection);
4318     ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres);
4319
4320     hres = IHTMLSelectionObject_createRange(selection, &disp_range);
4321     ok(hres == S_OK, "IHTMLSelectionObject_createRange failed: %08x\n", hres);
4322     IHTMLSelectionObject_Release(selection);
4323
4324     hres = IDispatch_QueryInterface(disp_range, &IID_IHTMLTxtRange, (void **)&range);
4325     ok(hres == S_OK, "Could not get IID_IHTMLTxtRange interface: 0x%08x\n", hres);
4326     IDispatch_Release(disp_range);
4327
4328     test_range_text(range, NULL);
4329     test_range_moveend(range, characterW, 3, 3);
4330     test_range_text(range, "wor");
4331     test_range_parent(range, ET_BODY);
4332     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
4333     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
4334     test_range_move(range, characterW, 3, 3);
4335     test_range_expand(range, wordW, VARIANT_TRUE, "wordabc ");
4336     test_range_moveend(range, characterW, -4, -4);
4337     test_range_put_text(range, "abc def ");
4338     test_range_expand(range, texteditW, VARIANT_TRUE, "abc def abc 123\r\nit's text");
4339     test_range_move(range, wordW, 1, 1);
4340     test_range_movestart(range, characterW, -1, -1);
4341     test_range_text(range, " ");
4342     test_range_move(range, wordW, 1, 1);
4343     test_range_moveend(range, characterW, 3, 3);
4344     test_range_text(range, "def");
4345     test_range_put_text(range, "xyz");
4346     test_range_moveend(range, characterW, 1, 1);
4347     test_range_move(range, wordW, 1, 1);
4348     test_range_moveend(range, characterW, 2, 2);
4349     test_range_text(range, "ab");
4350
4351     IHTMLTxtRange_Release(range);
4352 }
4353
4354 static void test_txtrange2(IHTMLDocument2 *doc)
4355 {
4356     IHTMLTxtRange *range;
4357
4358     range = test_create_body_range(doc);
4359
4360     test_range_text(range, "abc\r\n\r\n123\r\n\r\n\r\ndef");
4361     test_range_move(range, characterW, 5, 5);
4362     test_range_moveend(range, characterW, 1, 1);
4363     test_range_text(range, "2");
4364     test_range_move(range, characterW, -3, -3);
4365     test_range_moveend(range, characterW, 3, 3);
4366     test_range_text(range, "c\r\n\r\n1");
4367     test_range_collapse(range, VARIANT_FALSE);
4368     test_range_moveend(range, characterW, 4, 4);
4369     test_range_text(range, "23");
4370     test_range_moveend(range, characterW, 1, 1);
4371     test_range_text(range, "23\r\n\r\n\r\nd");
4372     test_range_moveend(range, characterW, -1, -1);
4373     test_range_text(range, "23");
4374     test_range_moveend(range, characterW, -1, -1);
4375     test_range_text(range, "23");
4376     test_range_moveend(range, characterW, -2, -2);
4377     test_range_text(range, "2");
4378
4379     IHTMLTxtRange_Release(range);
4380 }
4381
4382 static void test_compatmode(IHTMLDocument2 *doc)
4383 {
4384     IHTMLDocument5 *doc5;
4385     BSTR mode;
4386     HRESULT hres;
4387
4388     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
4389     ok(hres == S_OK, "Could not get IHTMLDocument5 interface: %08x\n", hres);
4390     if(FAILED(hres))
4391         return;
4392
4393     hres = IHTMLDocument5_get_compatMode(doc5, &mode);
4394     IHTMLDocument5_Release(doc5);
4395     ok(hres == S_OK, "get_compatMode failed: %08x\n", hres);
4396     ok(!strcmp_wa(mode, "BackCompat"), "compatMode=%s\n", wine_dbgstr_w(mode));
4397     SysFreeString(mode);
4398 }
4399
4400 static void test_location(IHTMLDocument2 *doc)
4401 {
4402     IHTMLLocation *location, *location2;
4403     IHTMLWindow2 *window;
4404     BSTR str;
4405     ULONG ref;
4406     HRESULT hres;
4407
4408     hres = IHTMLDocument2_get_location(doc, &location);
4409     ok(hres == S_OK, "get_location failed: %08x\n", hres);
4410
4411     hres = IHTMLDocument2_get_location(doc, &location2);
4412     ok(hres == S_OK, "get_location failed: %08x\n", hres);
4413
4414     ok(location == location2, "location != location2\n");
4415     IHTMLLocation_Release(location2);
4416
4417     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4418     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
4419
4420     hres = IHTMLWindow2_get_location(window, &location2);
4421     ok(hres == S_OK, "get_location failed: %08x\n", hres);
4422     ok(location == location2, "location != location2\n");
4423     IHTMLLocation_Release(location2);
4424
4425     test_ifaces((IUnknown*)location, location_iids);
4426     test_disp2((IUnknown*)location, &DIID_DispHTMLLocation, &IID_IHTMLLocation, "about:blank");
4427
4428     hres = IHTMLLocation_get_pathname(location, &str);
4429     ok(hres == S_OK, "get_pathname failed: %08x\n", hres);
4430     ok(!strcmp_wa(str, "blank"), "unexpected pathname %s\n", wine_dbgstr_w(str));
4431     SysFreeString(str);
4432
4433     hres = IHTMLLocation_get_href(location, NULL);
4434     ok(hres == E_POINTER, "get_href passed: %08x\n", hres);
4435
4436     hres = IHTMLLocation_get_href(location, &str);
4437     ok(hres == S_OK, "get_href failed: %08x\n", hres);
4438     ok(!strcmp_wa(str, "about:blank"), "unexpected href %s\n", wine_dbgstr_w(str));
4439     SysFreeString(str);
4440
4441     ref = IHTMLLocation_Release(location);
4442     ok(!ref, "location chould be destroyed here\n");
4443 }
4444
4445 static void test_plugins_col(IHTMLDocument2 *doc)
4446 {
4447     IHTMLPluginsCollection *col, *col2;
4448     IHTMLWindow2 *window;
4449     IOmNavigator *nav;
4450     ULONG ref;
4451     LONG len;
4452     HRESULT hres;
4453
4454     window = get_doc_window(doc);
4455     hres = IHTMLWindow2_get_navigator(window, &nav);
4456     IHTMLWindow2_Release(window);
4457
4458     hres = IOmNavigator_get_plugins(nav, &col);
4459     ok(hres == S_OK, "get_plugins failed: %08x\n", hres);
4460
4461     hres = IOmNavigator_get_plugins(nav, &col2);
4462     ok(hres == S_OK, "get_plugins failed: %08x\n", hres);
4463     ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n");
4464     IHTMLPluginsCollection_Release(col2);
4465
4466     test_disp2((IUnknown*)col, &DIID_DispCPlugins, &IID_IHTMLPluginsCollection, "[object]");
4467
4468     len = 0xdeadbeef;
4469     hres = IHTMLPluginsCollection_get_length(col, &len);
4470     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4471     ok(!len, "length = %d\n", len);
4472
4473     ref = IHTMLPluginsCollection_Release(col);
4474     ok(!ref, "ref=%d\n", ref);
4475
4476     IOmNavigator_Release(nav);
4477 }
4478
4479 static void test_mime_types_col(IOmNavigator *nav)
4480 {
4481     IHTMLMimeTypesCollection *col, *col2;
4482     LONG length;
4483     ULONG ref;
4484     HRESULT hres;
4485
4486     hres = IOmNavigator_get_mimeTypes(nav, &col);
4487     ok(hres == S_OK, "get_mimeTypes failed: %08x\n", hres);
4488
4489     hres = IOmNavigator_get_mimeTypes(nav, &col2);
4490     ok(hres == S_OK, "get_mimeTypes failed: %08x\n", hres);
4491     ok(iface_cmp((IUnknown*)col, (IUnknown*)col2), "col != col2\n");
4492     IHTMLMimeTypesCollection_Release(col2);
4493
4494     test_disp((IUnknown*)col, &IID_IHTMLMimeTypesCollection, "[object]");
4495
4496     length = 0xdeadbeef;
4497     hres = IHTMLMimeTypesCollection_get_length(col, &length);
4498     ok(hres == S_OK, "get_length failed: %08x\n", hres);
4499     ok(!length, "length = %d\n", length);
4500
4501     ref = IHTMLMimeTypesCollection_Release(col);
4502     ok(!ref, "ref=%d\n", ref);
4503 }
4504
4505 #define test_framebase_name(a,b) _test_framebase_name(__LINE__,a,b)
4506 static void _test_framebase_name(unsigned line, IHTMLElement *elem, const char *name)
4507 {
4508     BSTR str = (void*)0xdeadbeef;
4509     IHTMLFrameBase *fbase;
4510     HRESULT hres;
4511
4512     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
4513     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
4514
4515     hres = IHTMLFrameBase_get_name(fbase, &str);
4516     ok_(__FILE__,line)(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
4517     if(name)
4518         ok_(__FILE__,line)(!strcmp_wa(str, name), "name = %s, expected %s\n", wine_dbgstr_w(str), name);
4519     else
4520         ok_(__FILE__,line)(!str, "name = %s, expected NULL\n", wine_dbgstr_w(str));
4521     SysFreeString(str);
4522
4523     IHTMLFrameBase_Release(fbase);
4524 }
4525
4526 #define test_framebase_put_name(a,b) _test_framebase_put_name(__LINE__,a,b)
4527 static void _test_framebase_put_name(unsigned line, IHTMLElement *elem, const char *name)
4528 {
4529     IHTMLFrameBase *fbase;
4530     HRESULT hres;
4531     BSTR str;
4532
4533     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
4534     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
4535
4536     str = name ? a2bstr(name) : NULL;
4537     hres = IHTMLFrameBase_put_name(fbase, str);
4538     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
4539     SysFreeString(str);
4540
4541     _test_framebase_name(line, elem, name);
4542     IHTMLFrameBase_Release(fbase);
4543 }
4544
4545 #define test_framebase_marginheight(a,b) _test_framebase_marginheight(__LINE__,a,b)
4546 static void _test_framebase_marginheight(unsigned line, IHTMLFrameBase *framebase, const char *exval)
4547 {
4548     VARIANT v;
4549     HRESULT hres;
4550
4551     hres = IHTMLFrameBase_get_marginHeight(framebase, &v);
4552     ok_(__FILE__,line)(hres == S_OK, "get_marginHeight failed: %08x\n", hres);
4553     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(marginHeight) = %d\n", V_VT(&v));
4554     if(exval)
4555         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "marginHeight = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
4556     else
4557         ok_(__FILE__,line)(!V_BSTR(&v), "marginHeight = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
4558     VariantClear(&v);
4559 }
4560
4561 #define set_framebase_marginheight(a,b) _set_framebase_marginheight(__LINE__,a,b)
4562 static void _set_framebase_marginheight(unsigned line, IHTMLFrameBase *framebase, const char *val)
4563 {
4564     VARIANT v;
4565     HRESULT hres;
4566
4567     V_VT(&v) = VT_BSTR;
4568     V_BSTR(&v) = a2bstr(val);
4569     hres = IHTMLFrameBase_put_marginHeight(framebase, v);
4570     ok_(__FILE__,line)(hres == S_OK, "put_marginHeight failed: %08x\n", hres);
4571     VariantClear(&v);
4572 }
4573
4574 #define test_framebase_marginwidth(a,b) _test_framebase_marginwidth(__LINE__,a,b)
4575 static void _test_framebase_marginwidth(unsigned line, IHTMLFrameBase *framebase, const char *exval)
4576 {
4577     VARIANT v;
4578     HRESULT hres;
4579
4580     hres = IHTMLFrameBase_get_marginWidth(framebase, &v);
4581     ok_(__FILE__,line)(hres == S_OK, "get_marginWidth failed: %08x\n", hres);
4582     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(marginWidth) = %d\n", V_VT(&v));
4583     if(exval)
4584         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "marginWidth = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
4585     else
4586         ok_(__FILE__,line)(!V_BSTR(&v), "marginWidth = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
4587     VariantClear(&v);
4588 }
4589
4590 #define set_framebase_marginwidth(a,b) _set_framebase_marginwidth(__LINE__,a,b)
4591 static void _set_framebase_marginwidth(unsigned line, IHTMLFrameBase *framebase, const char *val)
4592 {
4593     VARIANT v;
4594     HRESULT hres;
4595
4596     V_VT(&v) = VT_BSTR;
4597     V_BSTR(&v) = a2bstr(val);
4598     hres = IHTMLFrameBase_put_marginWidth(framebase, v);
4599     ok_(__FILE__,line)(hres == S_OK, "put_marginWidth failed: %08x\n", hres);
4600     VariantClear(&v);
4601 }
4602
4603 static void test_framebase(IUnknown *unk)
4604 {
4605     IHTMLFrameBase *fbase;
4606     BSTR str;
4607     HRESULT hres;
4608
4609     /* get/put scrolling */
4610     hres = IUnknown_QueryInterface(unk, &IID_IHTMLFrameBase, (void**)&fbase);
4611     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
4612
4613     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
4614     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
4615     ok(!strcmp_wa(str, "auto"), "get_scrolling should have given 'auto', gave: %s\n", wine_dbgstr_w(str));
4616     SysFreeString(str);
4617
4618     str = a2bstr("no");
4619     hres = IHTMLFrameBase_put_scrolling(fbase, str);
4620     ok(hres == S_OK, "IHTMLFrameBase_put_scrolling failed: 0x%08x\n", hres);
4621     SysFreeString(str);
4622
4623     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
4624     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
4625     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
4626     SysFreeString(str);
4627
4628     str = a2bstr("junk");
4629     hres = IHTMLFrameBase_put_scrolling(fbase, str);
4630     ok(hres == E_INVALIDARG, "IHTMLFrameBase_put_scrolling should have failed "
4631             "with E_INVALIDARG, instead: 0x%08x\n", hres);
4632     SysFreeString(str);
4633
4634     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
4635     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
4636     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
4637     SysFreeString(str);
4638
4639     hres = IHTMLFrameBase_get_frameBorder(fbase, &str);
4640     ok(hres == S_OK, "get_frameBorder failed: %08x\n", hres);
4641     ok(!str, "frameBorder = %s\n", wine_dbgstr_w(str));
4642
4643     str = a2bstr("1");
4644     hres = IHTMLFrameBase_put_frameBorder(fbase, str);
4645     ok(hres == S_OK, "put_frameBorder failed: %08x\n", hres);
4646     SysFreeString(str);
4647
4648     hres = IHTMLFrameBase_get_frameBorder(fbase, &str);
4649     ok(hres == S_OK, "get_frameBorder failed: %08x\n", hres);
4650     ok(!strcmp_wa(str, "1"), "frameBorder = %s, expected \"1\"\n", wine_dbgstr_w(str));
4651
4652     test_framebase_marginheight(fbase, NULL);
4653     set_framebase_marginheight(fbase, "1px");
4654     test_framebase_marginheight(fbase, "1");
4655
4656     test_framebase_marginwidth(fbase, NULL);
4657     set_framebase_marginwidth(fbase, "2px");
4658     test_framebase_marginwidth(fbase, "2");
4659
4660     IHTMLFrameBase_Release(fbase);
4661 }
4662
4663 #define test_language_string(a,b) _test_language_string(__LINE__,a,b)
4664 static void _test_language_string(unsigned line, const WCHAR *lang, LCID lcid)
4665 {
4666     WCHAR buf[64];
4667     int res;
4668
4669     if(pLCIDToLocaleName) {
4670         res = pLCIDToLocaleName(lcid, buf, sizeof(buf)/sizeof(WCHAR), 0);
4671         ok_(__FILE__,line)(res, "LCIDToLocaleName failed: %u\n", GetLastError());
4672         ok_(__FILE__,line)(!lstrcmpW(lang, buf), "lang = %s, expected %s\n", wine_dbgstr_w(lang), wine_dbgstr_w(buf));
4673     }else {
4674         win_skip("LCIDToLocaleName not available, unable to test language string\n");
4675         ok_(__FILE__,line)(lang != NULL, "lang == NULL\n");
4676     }
4677 }
4678
4679 static void test_navigator(IHTMLDocument2 *doc)
4680 {
4681     IHTMLWindow2 *window;
4682     IOmNavigator *navigator, *navigator2;
4683     VARIANT_BOOL b;
4684     char buf[512];
4685     DWORD size;
4686     ULONG ref;
4687     BSTR bstr;
4688     HRESULT hres;
4689
4690     static const WCHAR v40[] = {'4','.','0'};
4691
4692     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4693     ok(hres == S_OK, "parentWidnow failed: %08x\n", hres);
4694
4695     hres = IHTMLWindow2_get_navigator(window, &navigator);
4696     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
4697     ok(navigator != NULL, "navigator == NULL\n");
4698     test_disp2((IUnknown*)navigator, &DIID_DispHTMLNavigator, &IID_IOmNavigator, "[object]");
4699
4700     hres = IHTMLWindow2_get_navigator(window, &navigator2);
4701     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
4702     ok(navigator != navigator2, "navigator2 != navihgator\n");
4703
4704     IHTMLWindow2_Release(window);
4705     IOmNavigator_Release(navigator2);
4706
4707     hres = IOmNavigator_get_appCodeName(navigator, &bstr);
4708     ok(hres == S_OK, "get_appCodeName failed: %08x\n", hres);
4709     ok(!strcmp_wa(bstr, "Mozilla"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
4710     SysFreeString(bstr);
4711
4712     bstr = NULL;
4713     hres = IOmNavigator_get_appName(navigator, &bstr);
4714     ok(hres == S_OK, "get_appName failed: %08x\n", hres);
4715     ok(!strcmp_wa(bstr, "Microsoft Internet Explorer"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
4716     SysFreeString(bstr);
4717
4718     bstr = NULL;
4719     hres = IOmNavigator_get_platform(navigator, &bstr);
4720     ok(hres == S_OK, "get_platform failed: %08x\n", hres);
4721     ok(!strcmp_wa(bstr, sizeof(void*) == 8 ? "Win64" : "Win32")
4722        || (sizeof(void*) == 8 && broken(!strcmp_wa(bstr, "Win32") /* IE6 */)), "unexpected platform %s\n", wine_dbgstr_w(bstr));
4723     SysFreeString(bstr);
4724
4725     bstr = NULL;
4726     hres = IOmNavigator_get_cpuClass(navigator, &bstr);
4727     ok(hres == S_OK, "get_cpuClass failed: %08x\n", hres);
4728     ok(!strcmp_wa(bstr, sizeof(void*) == 8 ? "x64" : "x86"), "unexpected cpuClass %s\n", wine_dbgstr_w(bstr));
4729     SysFreeString(bstr);
4730
4731     bstr = NULL;
4732     hres = IOmNavigator_get_appVersion(navigator, &bstr);
4733     ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
4734     ok(!memcmp(bstr, v40, sizeof(v40)), "appVersion is %s\n", wine_dbgstr_w(bstr));
4735     SysFreeString(bstr);
4736
4737     bstr = NULL;
4738     hres = IOmNavigator_get_systemLanguage(navigator, &bstr);
4739     ok(hres == S_OK, "get_systemLanguage failed: %08x\n", hres);
4740     test_language_string(bstr, LOCALE_SYSTEM_DEFAULT);
4741     SysFreeString(bstr);
4742
4743     if (pGetUserDefaultUILanguage)
4744     {
4745         bstr = NULL;
4746         hres = IOmNavigator_get_browserLanguage(navigator, &bstr);
4747         ok(hres == S_OK, "get_browserLanguage failed: %08x\n", hres);
4748         test_language_string(bstr, pGetUserDefaultUILanguage());
4749         SysFreeString(bstr);
4750     }
4751     else
4752         win_skip("GetUserDefaultUILanguage not available\n");
4753
4754     bstr = NULL;
4755     hres = IOmNavigator_get_userLanguage(navigator, &bstr);
4756     ok(hres == S_OK, "get_userLanguage failed: %08x\n", hres);
4757     test_language_string(bstr, LOCALE_USER_DEFAULT);
4758     SysFreeString(bstr);
4759
4760     hres = IOmNavigator_toString(navigator, NULL);
4761     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
4762
4763     bstr = NULL;
4764     hres = IOmNavigator_toString(navigator, &bstr);
4765     ok(hres == S_OK, "toString failed: %08x\n", hres);
4766     ok(!strcmp_wa(bstr, "[object]"), "toString returned %s\n", wine_dbgstr_w(bstr));
4767     SysFreeString(bstr);
4768
4769     b = 100;
4770     hres = IOmNavigator_get_onLine(navigator, &b);
4771     ok(hres == S_OK, "get_onLine failed: %08x\n", hres);
4772     ok(b == VARIANT_TRUE, "onLine = %x\n", b);
4773
4774     size = sizeof(buf);
4775     hres = ObtainUserAgentString(0, buf, &size);
4776     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
4777
4778     bstr = NULL;
4779     hres = IOmNavigator_get_userAgent(navigator, &bstr);
4780     ok(hres == S_OK, "get_userAgent failed: %08x\n", hres);
4781     ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf);
4782     SysFreeString(bstr);
4783
4784     if(!strncmp(buf, "Mozilla/", 8)) {
4785         bstr = NULL;
4786         hres = IOmNavigator_get_appVersion(navigator, &bstr);
4787         ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
4788         ok(!strcmp_wa(bstr, buf+8), "appVersion returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf+8);
4789         SysFreeString(bstr);
4790     }else {
4791         skip("nonstandard user agent\n");
4792     }
4793
4794     bstr = NULL;
4795     hres = IOmNavigator_get_appMinorVersion(navigator, &bstr);
4796     ok(hres == S_OK, "get_appMonorVersion failed: %08x\n", hres);
4797     ok(bstr != NULL, "appMinorVersion returned NULL\n");
4798     SysFreeString(bstr);
4799
4800     test_mime_types_col(navigator);
4801
4802     ref = IOmNavigator_Release(navigator);
4803     ok(!ref, "navigator should be destroyed here\n");
4804 }
4805
4806 static void test_screen(IHTMLWindow2 *window)
4807 {
4808     IHTMLScreen *screen, *screen2;
4809     IDispatchEx *dispex;
4810     RECT work_area;
4811     LONG l, exl;
4812     HDC hdc;
4813     HRESULT hres;
4814
4815     screen = NULL;
4816     hres = IHTMLWindow2_get_screen(window, &screen);
4817     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
4818     ok(screen != NULL, "screen == NULL\n");
4819
4820     screen2 = NULL;
4821     hres = IHTMLWindow2_get_screen(window, &screen2);
4822     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
4823     ok(screen2 != NULL, "screen == NULL\n");
4824     ok(iface_cmp((IUnknown*)screen2, (IUnknown*)screen), "screen2 != screen\n");
4825     IHTMLScreen_Release(screen2);
4826
4827     hres = IHTMLScreen_QueryInterface(screen, &IID_IDispatchEx, (void**)&dispex);
4828     ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres);
4829     if(SUCCEEDED(hres)) {
4830         test_disp((IUnknown*)screen, &DIID_DispHTMLScreen, "[object]");
4831         IDispatchEx_Release(dispex);
4832     }
4833
4834     hdc = CreateICA("DISPLAY", NULL, NULL, NULL);
4835
4836     exl = GetDeviceCaps(hdc, HORZRES);
4837     l = 0xdeadbeef;
4838     hres = IHTMLScreen_get_width(screen, &l);
4839     ok(hres == S_OK, "get_width failed: %08x\n", hres);
4840     ok(l == exl, "width = %d, expected %d\n", l, exl);
4841
4842     exl = GetDeviceCaps(hdc, VERTRES);
4843     l = 0xdeadbeef;
4844     hres = IHTMLScreen_get_height(screen, &l);
4845     ok(hres == S_OK, "get_height failed: %08x\n", hres);
4846     ok(l == exl, "height = %d, expected %d\n", l, exl);
4847
4848     exl = GetDeviceCaps(hdc, BITSPIXEL);
4849     l = 0xdeadbeef;
4850     hres = IHTMLScreen_get_colorDepth(screen, &l);
4851     ok(hres == S_OK, "get_height failed: %08x\n", hres);
4852     ok(l == exl, "height = %d, expected %d\n", l, exl);
4853
4854     DeleteObject(hdc);
4855
4856     SystemParametersInfoW(SPI_GETWORKAREA, 0, &work_area, 0);
4857
4858     l = 0xdeadbeef;
4859     hres = IHTMLScreen_get_availHeight(screen, &l);
4860     ok(hres == S_OK, "get_availHeight failed: %08x\n", hres);
4861     ok(l == work_area.bottom-work_area.top, "availHeight = %d, expected %d\n", l, work_area.bottom-work_area.top);
4862
4863     l = 0xdeadbeef;
4864     hres = IHTMLScreen_get_availWidth(screen, &l);
4865     ok(hres == S_OK, "get_availWidth failed: %08x\n", hres);
4866     ok(l == work_area.right-work_area.left, "availWidth = %d, expected %d\n", l, work_area.right-work_area.left);
4867
4868     IHTMLScreen_Release(screen);
4869 }
4870
4871 static void test_default_selection(IHTMLDocument2 *doc)
4872 {
4873     IHTMLSelectionObject *selection;
4874     IHTMLTxtRange *range;
4875     IDispatch *disp;
4876     BSTR str;
4877     HRESULT hres;
4878
4879     hres = IHTMLDocument2_get_selection(doc, &selection);
4880     ok(hres == S_OK, "get_selection failed: %08x\n", hres);
4881
4882     hres = IHTMLSelectionObject_get_type(selection, &str);
4883     ok(hres == S_OK, "get_type failed: %08x\n", hres);
4884     ok(!strcmp_wa(str, "None"), "type = %s\n", wine_dbgstr_w(str));
4885     SysFreeString(str);
4886
4887     hres = IHTMLSelectionObject_createRange(selection, &disp);
4888     IHTMLSelectionObject_Release(selection);
4889     ok(hres == S_OK, "createRange failed: %08x\n", hres);
4890
4891     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTxtRange, (void**)&range);
4892     IDispatch_Release(disp);
4893     ok(hres == S_OK, "Could not get IHTMLTxtRange interface: %08x\n", hres);
4894
4895     test_range_text(range, NULL);
4896     IHTMLTxtRange_Release(range);
4897 }
4898
4899 static void test_doc_elem(IHTMLDocument2 *doc)
4900 {
4901     IHTMLDocument2 *doc_node, *owner_doc;
4902     IHTMLElement *elem;
4903     IHTMLDocument3 *doc3;
4904     HRESULT hres;
4905
4906     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4907     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
4908
4909     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
4910     IHTMLDocument3_Release(doc3);
4911     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
4912
4913     test_node_name((IUnknown*)elem, "HTML");
4914     test_elem_tag((IUnknown*)elem, "HTML");
4915
4916     doc_node = get_doc_node(doc);
4917     owner_doc = get_owner_doc((IUnknown*)elem);
4918     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
4919     IHTMLDocument2_Release(owner_doc);
4920
4921     owner_doc = get_owner_doc((IUnknown*)doc_node);
4922     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
4923     IHTMLDocument2_Release(doc_node);
4924
4925     test_elem_client_rect((IUnknown*)elem);
4926
4927     IHTMLElement_Release(elem);
4928 }
4929
4930 static void test_default_body(IHTMLBodyElement *body)
4931 {
4932     LONG l;
4933     BSTR bstr;
4934     HRESULT hres;
4935     VARIANT v;
4936
4937     bstr = (void*)0xdeadbeef;
4938     hres = IHTMLBodyElement_get_background(body, &bstr);
4939     ok(hres == S_OK, "get_background failed: %08x\n", hres);
4940     ok(bstr == NULL, "bstr != NULL\n");
4941
4942     l = elem_get_scroll_height((IUnknown*)body);
4943     ok(l != -1, "scrollHeight == -1\n");
4944     l = elem_get_scroll_width((IUnknown*)body);
4945     ok(l != -1, "scrollWidth == -1\n");
4946     l = elem_get_scroll_top((IUnknown*)body);
4947     ok(!l, "scrollTop = %d\n", l);
4948     elem_get_scroll_left((IUnknown*)body);
4949
4950     /* get_text tests */
4951     hres = IHTMLBodyElement_get_text(body, &v);
4952     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4953     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4954     ok(V_BSTR(&v) == NULL, "bstr != NULL\n");
4955
4956     /* get_text - Invalid Text */
4957     V_VT(&v) = VT_BSTR;
4958     V_BSTR(&v) = a2bstr("Invalid");
4959     hres = IHTMLBodyElement_put_text(body, v);
4960     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4961     VariantClear(&v);
4962
4963     V_VT(&v) = VT_NULL;
4964     hres = IHTMLBodyElement_get_text(body, &v);
4965     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4966     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4967     ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v = %s, expected '#00a0d0'\n", wine_dbgstr_w(V_BSTR(&v)));
4968     VariantClear(&v);
4969
4970     /* get_text - Valid Text */
4971     V_VT(&v) = VT_BSTR;
4972     V_BSTR(&v) = a2bstr("#FF0000");
4973     hres = IHTMLBodyElement_put_text(body, v);
4974     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4975     VariantClear(&v);
4976
4977     V_VT(&v) = VT_NULL;
4978     hres = IHTMLBodyElement_get_text(body, &v);
4979     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4980     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4981     ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v = %s, expected '#ff0000'\n", wine_dbgstr_w(V_BSTR(&v)));
4982     VariantClear(&v);
4983 }
4984
4985 static void test_body_funs(IHTMLBodyElement *body)
4986 {
4987     VARIANT vbg, vDefaultbg;
4988     HRESULT hres;
4989
4990     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
4991     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4992     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
4993     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
4994
4995     V_VT(&vbg) = VT_BSTR;
4996     V_BSTR(&vbg) = a2bstr("red");
4997     hres = IHTMLBodyElement_put_bgColor(body, vbg);
4998     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4999     VariantClear(&vbg);
5000
5001     hres = IHTMLBodyElement_get_bgColor(body, &vbg);
5002     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
5003     ok(V_VT(&vDefaultbg) == VT_BSTR, "V_VT(&vDefaultbg) != VT_BSTR\n");
5004     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
5005     VariantClear(&vbg);
5006
5007     /* Restore Originial */
5008     hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg);
5009     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
5010     VariantClear(&vDefaultbg);
5011 }
5012
5013 static void test_history(IHTMLWindow2 *window)
5014 {
5015     IOmHistory *history, *history2;
5016     HRESULT hres;
5017
5018     history = NULL;
5019     hres = IHTMLWindow2_get_history(window, &history);
5020     ok(hres == S_OK, "get_history failed: %08x\n", hres);
5021     ok(history != NULL, "history = NULL\n");
5022
5023     test_disp2((IUnknown*)history, &DIID_DispHTMLHistory, &IID_IOmHistory, "[object]");
5024
5025     history2 = NULL;
5026     hres = IHTMLWindow2_get_history(window, &history2);
5027     ok(hres == S_OK, "get_history failed: %08x\n", hres);
5028     ok(history2 != NULL, "history2 = NULL\n");
5029     ok(iface_cmp((IUnknown*)history, (IUnknown*)history2), "history != history2\n");
5030
5031     IOmHistory_Release(history2);
5032     IOmHistory_Release(history);
5033 }
5034
5035 static void test_window(IHTMLDocument2 *doc)
5036 {
5037     IHTMLWindow2 *window, *window2, *self, *parent;
5038     IHTMLDocument2 *doc2 = NULL;
5039     IDispatch *disp;
5040     IUnknown *unk;
5041     VARIANT v;
5042     BSTR str;
5043     HRESULT hres;
5044
5045     hres = IHTMLDocument2_get_parentWindow(doc, &window);
5046     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
5047     test_ifaces((IUnknown*)window, window_iids);
5048     hres = IHTMLWindow2_QueryInterface(window, &IID_ITravelLogClient, (void**)&unk);
5049     if(hres == S_OK)
5050         IUnknown_Release(unk);
5051     else
5052         win_skip("IID_ITravelLogClient not supported\n");
5053
5054     test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, "[object]");
5055
5056     hres = IHTMLWindow2_get_document(window, &doc2);
5057     ok(hres == S_OK, "get_document failed: %08x\n", hres);
5058     ok(doc2 != NULL, "doc2 == NULL\n");
5059
5060     test_ifaces((IUnknown*)doc2, doc_node_iids);
5061     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
5062     test_class_info((IUnknown*)doc2);
5063
5064     test_ifaces((IUnknown*)doc, doc_obj_iids);
5065     test_disp((IUnknown*)doc, &DIID_DispHTMLDocument, "[object]");
5066     test_class_info((IUnknown*)doc);
5067
5068     unk = (void*)0xdeadbeef;
5069     hres = IHTMLDocument2_QueryInterface(doc2, &IID_ICustomDoc, (void**)&unk);
5070     ok(hres == E_NOINTERFACE, "QueryInterface(IID_ICustomDoc) returned: %08x\n", hres);
5071     ok(!unk, "unk = %p\n", unk);
5072
5073     IHTMLDocument2_Release(doc2);
5074
5075     hres = IHTMLWindow2_get_window(window, &window2);
5076     ok(hres == S_OK, "get_window failed: %08x\n", hres);
5077     ok(window2 != NULL, "window2 == NULL\n");
5078
5079     hres = IHTMLWindow2_get_self(window, &self);
5080     ok(hres == S_OK, "get_self failed: %08x\n", hres);
5081     ok(window2 != NULL, "self == NULL\n");
5082
5083     ok(self == window2, "self != window2\n");
5084
5085     IHTMLWindow2_Release(window2);
5086
5087     disp = NULL;
5088     hres = IHTMLDocument2_get_Script(doc, &disp);
5089     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
5090     ok(disp == (void*)window, "disp != window\n");
5091     IDispatch_Release(disp);
5092
5093     hres = IHTMLWindow2_toString(window, NULL);
5094     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
5095
5096     str = NULL;
5097     hres = IHTMLWindow2_toString(window, &str);
5098     ok(hres == S_OK, "toString failed: %08x\n", hres);
5099     ok(!strcmp_wa(str, "[object]") ||
5100        !strcmp_wa(str, "[object Window]") /* win7 ie9 */, "toString returned %s\n", wine_dbgstr_w(str));
5101     SysFreeString(str);
5102
5103     V_VT(&v) = VT_ERROR;
5104     hres = IHTMLWindow2_get_opener(window, &v);
5105     ok(hres == S_OK, "get_opener failed: %08x\n", hres);
5106     ok(V_VT(&v) == VT_EMPTY, "V_VT(opener) = %d\n", V_VT(&v));
5107
5108     parent = NULL;
5109     hres = IHTMLWindow2_get_parent(window, &parent);
5110     ok(hres == S_OK, "get_parent failed: %08x\n", hres);
5111     ok(parent != NULL, "parent == NULL\n");
5112     ok(parent == self, "parent != window\n");
5113     IHTMLWindow2_Release(parent);
5114     IHTMLWindow2_Release(self);
5115
5116     test_window_name(window, NULL);
5117     set_window_name(window, "test");
5118     test_window_length(window, 0);
5119     test_screen(window);
5120     test_window_status(window);
5121     set_window_status(window, "Test!");
5122     test_history(window);
5123
5124     IHTMLWindow2_Release(window);
5125 }
5126
5127 static void test_defaults(IHTMLDocument2 *doc)
5128 {
5129     IHTMLStyleSheetsCollection *stylesheetcol;
5130     IHTMLCurrentStyle *cstyle;
5131     IHTMLBodyElement *body;
5132     IHTMLElement2 *elem2;
5133     IHTMLElement *elem;
5134     IHTMLStyle *style;
5135     BSTR str;
5136     LONG l;
5137     HRESULT hres;
5138     IHTMLElementCollection *collection;
5139
5140     elem = doc_get_body(doc);
5141
5142     hres = IHTMLDocument2_get_images(doc, NULL);
5143     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5144
5145     hres = IHTMLDocument2_get_images(doc, &collection);
5146     ok(hres == S_OK, "get_images failed: %08x\n", hres);
5147     if(hres == S_OK)
5148     {
5149         test_elem_collection((IUnknown*)collection, NULL, 0);
5150         IHTMLElementCollection_Release(collection);
5151     }
5152
5153     hres = IHTMLDocument2_get_applets(doc, NULL);
5154     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5155
5156     hres = IHTMLDocument2_get_applets(doc, &collection);
5157     ok(hres == S_OK, "get_applets failed: %08x\n", hres);
5158     if(hres == S_OK)
5159     {
5160         test_elem_collection((IUnknown*)collection, NULL, 0);
5161         IHTMLElementCollection_Release(collection);
5162     }
5163
5164     hres = IHTMLDocument2_get_links(doc, NULL);
5165     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5166
5167     hres = IHTMLDocument2_get_links(doc, &collection);
5168     ok(hres == S_OK, "get_links failed: %08x\n", hres);
5169     if(hres == S_OK)
5170     {
5171         test_elem_collection((IUnknown*)collection, NULL, 0);
5172         IHTMLElementCollection_Release(collection);
5173     }
5174
5175     hres = IHTMLDocument2_get_forms(doc, NULL);
5176     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5177
5178     hres = IHTMLDocument2_get_forms(doc, &collection);
5179     ok(hres == S_OK, "get_forms failed: %08x\n", hres);
5180     if(hres == S_OK)
5181     {
5182         test_elem_collection((IUnknown*)collection, NULL, 0);
5183         IHTMLElementCollection_Release(collection);
5184     }
5185
5186     hres = IHTMLDocument2_get_anchors(doc, NULL);
5187     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5188
5189     hres = IHTMLDocument2_get_anchors(doc, &collection);
5190     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5191     if(hres == S_OK)
5192     {
5193         test_elem_collection((IUnknown*)collection, NULL, 0);
5194         IHTMLElementCollection_Release(collection);
5195     }
5196
5197     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
5198     ok(hres == S_OK, "Could not get IHTMBodyElement: %08x\n", hres);
5199     test_default_body(body);
5200     test_body_funs(body);
5201     IHTMLBodyElement_Release(body);
5202
5203     hres = IHTMLElement_get_style(elem, &style);
5204     ok(hres == S_OK, "get_style failed: %08x\n", hres);
5205
5206     test_disp((IUnknown*)style, &DIID_DispHTMLStyle, "[object]");
5207     test_ifaces((IUnknown*)style, style_iids);
5208     IHTMLStyle_Release(style);
5209
5210     str = NULL;
5211     hres = IHTMLDocument2_get_charset(doc, &str);
5212     ok(hres == S_OK, "get_charset failed: %08x\n", hres);
5213     ok(str && *str, "charset is empty\n"); /* FIXME: better tests */
5214     SysFreeString(str);
5215
5216     test_window(doc);
5217     test_compatmode(doc);
5218     test_location(doc);
5219     test_navigator(doc);
5220     test_plugins_col(doc);
5221
5222     elem2 = get_elem2_iface((IUnknown*)elem);
5223     hres = IHTMLElement2_get_currentStyle(elem2, &cstyle);
5224     ok(hres == S_OK, "get_currentStyle failed: %08x\n", hres);
5225     if(SUCCEEDED(hres)) {
5226         IUnknown *unk;
5227
5228         test_disp((IUnknown*)cstyle, &DIID_DispHTMLCurrentStyle, "[object]");
5229         test_ifaces((IUnknown*)cstyle, cstyle_iids);
5230
5231         hres = IHTMLCurrentStyle_QueryInterface(cstyle, &IID_IHTMLCurrentStyle4, (void**)&unk);
5232         if(SUCCEEDED(hres))
5233             IUnknown_Release(unk);
5234         else
5235         {
5236            /*IE6 doesn't have interface */
5237            win_skip("IID_IHTMLCurrentStyle4 not supported\n");
5238         }
5239
5240         IHTMLCurrentStyle_Release(cstyle);
5241     }
5242     IHTMLElement2_Release(elem2);
5243
5244     IHTMLElement_Release(elem);
5245
5246     hres = IHTMLDocument2_get_styleSheets(doc, &stylesheetcol);
5247     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5248
5249     l = 0xdeadbeef;
5250     hres = IHTMLStyleSheetsCollection_get_length(stylesheetcol, &l);
5251     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5252     ok(l == 0, "length = %d\n", l);
5253
5254     IHTMLStyleSheetsCollection_Release(stylesheetcol);
5255
5256     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFiltersCollection, (void**)&body);
5257     ok(hres == E_NOINTERFACE, "got interface IHTMLFiltersCollection\n");
5258
5259     test_default_selection(doc);
5260     test_doc_title(doc, "");
5261 }
5262
5263 static void test_tr_elem(IHTMLElement *elem)
5264 {
5265     IHTMLElementCollection *col;
5266     IHTMLTableRow *row;
5267     HRESULT hres;
5268
5269     static const elem_type_t cell_types[] = {ET_TD,ET_TD};
5270
5271     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableRow, (void**)&row);
5272     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
5273     if(FAILED(hres))
5274         return;
5275
5276     col = NULL;
5277     hres = IHTMLTableRow_get_cells(row, &col);
5278     ok(hres == S_OK, "get_cells failed: %08x\n", hres);
5279     ok(col != NULL, "get_cells returned NULL\n");
5280
5281     test_elem_collection((IUnknown*)col, cell_types, sizeof(cell_types)/sizeof(*cell_types));
5282     IHTMLElementCollection_Release(col);
5283
5284     IHTMLTableRow_Release(row);
5285 }
5286
5287 static void test_table_elem(IHTMLElement *elem)
5288 {
5289     IHTMLElementCollection *col;
5290     IHTMLTable *table;
5291     IHTMLDOMNode *node;
5292     HRESULT hres;
5293
5294     static const elem_type_t row_types[] = {ET_TR,ET_TR};
5295     static const elem_type_t all_types[] = {ET_TBODY,ET_TR,ET_TR,ET_TD,ET_TD};
5296
5297     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable, (void**)&table);
5298     ok(hres == S_OK, "Could not get IHTMLTable iface: %08x\n", hres);
5299     if(FAILED(hres))
5300         return;
5301
5302     col = NULL;
5303     hres = IHTMLTable_get_rows(table, &col);
5304     ok(hres == S_OK, "get_rows failed: %08x\n", hres);
5305     ok(col != NULL, "get_ros returned NULL\n");
5306
5307     test_elem_collection((IUnknown*)col, row_types, sizeof(row_types)/sizeof(*row_types));
5308     IHTMLElementCollection_Release(col);
5309
5310     test_elem_all((IUnknown*)table, all_types, sizeof(all_types)/sizeof(*all_types));
5311
5312     node = clone_node((IUnknown*)table, VARIANT_TRUE);
5313     test_elem_tag((IUnknown*)node, "TABLE");
5314     test_elem_all((IUnknown*)node, all_types, sizeof(all_types)/sizeof(*all_types));
5315     IHTMLDOMNode_Release(node);
5316
5317     node = clone_node((IUnknown*)table, VARIANT_FALSE);
5318     test_elem_tag((IUnknown*)node, "TABLE");
5319     test_elem_all((IUnknown*)node, NULL, 0);
5320     IHTMLDOMNode_Release(node);
5321
5322     IHTMLTable_Release(table);
5323 }
5324
5325 static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
5326 {
5327     SAFEARRAYBOUND dim;
5328     SAFEARRAY *sa;
5329     VARIANT *var;
5330     HRESULT hres;
5331
5332     dim.lLbound = 0;
5333     dim.cElements = 1;
5334     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
5335     SafeArrayAccessData(sa, (void**)&var);
5336     V_VT(var) = VT_BSTR;
5337     V_BSTR(var) = a2bstr(text);
5338     SafeArrayUnaccessData(sa);
5339
5340     if(ln)
5341         hres = IHTMLDocument2_writeln(doc, sa);
5342     else
5343         hres = IHTMLDocument2_write(doc, sa);
5344     ok(hres == S_OK, "write failed: %08x\n", hres);
5345
5346     SafeArrayDestroy(sa);
5347 }
5348
5349 static void doc_complex_write(IHTMLDocument2 *doc)
5350 {
5351     SAFEARRAYBOUND dim = {5, 0};
5352     SAFEARRAY *sa;
5353     VARIANT *args;
5354     HRESULT hres;
5355
5356     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
5357     SafeArrayAccessData(sa, (void**)&args);
5358
5359     V_VT(args) = VT_BSTR;
5360     V_BSTR(args) = a2bstr("<body i4val=\"");
5361     V_VT(args+1) = VT_I4;
5362     V_I4(args+1) = 4;
5363     V_VT(args+2) = VT_BSTR;
5364     V_BSTR(args+2) = a2bstr("\" r8val=\"");
5365     V_VT(args+3) = VT_R8;
5366     V_R8(args+3) = 3.14;
5367     V_VT(args+4) = VT_BSTR;
5368     V_BSTR(args+4) = a2bstr("\">");
5369     SafeArrayUnaccessData(sa);
5370
5371     hres = IHTMLDocument2_write(doc, sa);
5372     ok(hres == S_OK, "write failed: %08x\n", hres);
5373
5374     SafeArrayDestroy(sa);
5375 }
5376
5377 static void test_frame_doc(IUnknown *frame_elem, BOOL iframe)
5378 {
5379     IHTMLDocument2 *window_doc, *elem_doc;
5380     IHTMLFrameElement3 *frame_elem3;
5381     IHTMLWindow2 *content_window;
5382     HRESULT hres;
5383
5384     content_window = get_frame_content_window(frame_elem);
5385     test_ifaces((IUnknown*)content_window, window_iids);
5386     window_doc = get_window_doc(content_window);
5387     IHTMLWindow2_Release(content_window);
5388
5389     elem_doc = get_elem_doc(frame_elem);
5390     ok(iface_cmp((IUnknown*)window_doc, (IUnknown*)elem_doc), "content_doc != elem_doc\n");
5391
5392     if(!iframe) {
5393         hres = IUnknown_QueryInterface(frame_elem, &IID_IHTMLFrameElement3, (void**)&frame_elem3);
5394         if(SUCCEEDED(hres)) {
5395             IDispatch *disp = NULL;
5396
5397             hres = IHTMLFrameElement3_get_contentDocument(frame_elem3, &disp);
5398             ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
5399             ok(disp != NULL, "contentDocument == NULL\n");
5400             ok(iface_cmp((IUnknown*)disp, (IUnknown*)window_doc), "contentDocument != contentWindow.document\n");
5401
5402             IDispatch_Release(disp);
5403             IHTMLFrameElement3_Release(frame_elem3);
5404         }else {
5405             win_skip("IHTMLFrameElement3 not supported\n");
5406         }
5407     }
5408
5409     IHTMLDocument2_Release(elem_doc);
5410     IHTMLDocument2_Release(window_doc);
5411 }
5412
5413 #define test_iframe_height(a,b) _test_iframe_height(__LINE__,a,b)
5414 static void _test_iframe_height(unsigned line, IHTMLElement *elem, const char *exval)
5415 {
5416     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5417     VARIANT v;
5418     HRESULT hres;
5419
5420     hres = IHTMLIFrameElement2_get_height(iframe, &v);
5421     ok_(__FILE__,line)(hres == S_OK, "get_height failed: %08x\n", hres);
5422     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(height) = %d\n", V_VT(&v));
5423     if(exval)
5424         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "height = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
5425     else
5426         ok_(__FILE__,line)(!V_BSTR(&v), "height = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
5427     VariantClear(&v);
5428     IHTMLIFrameElement2_Release(iframe);
5429 }
5430
5431 #define set_iframe_height(a,b) _set_iframe_height(__LINE__,a,b)
5432 static void _set_iframe_height(unsigned line, IHTMLElement *elem, const char *val)
5433 {
5434     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5435     VARIANT v;
5436     HRESULT hres;
5437
5438     V_VT(&v) = VT_BSTR;
5439     V_BSTR(&v) = a2bstr(val);
5440     hres = IHTMLIFrameElement2_put_height(iframe, v);
5441     ok_(__FILE__,line)(hres == S_OK, "put_height failed: %08x\n", hres);
5442     VariantClear(&v);
5443     IHTMLIFrameElement2_Release(iframe);
5444 }
5445
5446 #define test_iframe_width(a,b) _test_iframe_width(__LINE__,a,b)
5447 static void _test_iframe_width(unsigned line, IHTMLElement *elem, const char *exval)
5448 {
5449     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5450     VARIANT v;
5451     HRESULT hres;
5452
5453     hres = IHTMLIFrameElement2_get_width(iframe, &v);
5454     ok_(__FILE__,line)(hres == S_OK, "get_width failed: %08x\n", hres);
5455     ok_(__FILE__,line)(V_VT(&v) == VT_BSTR, "V_VT(width) = %d\n", V_VT(&v));
5456     if(exval)
5457         ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&v), exval), "width = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&v)), exval);
5458     else
5459         ok_(__FILE__,line)(!V_BSTR(&v), "width = %s, expected NULL\n", wine_dbgstr_w(V_BSTR(&v)));
5460     VariantClear(&v);
5461     IHTMLIFrameElement2_Release(iframe);
5462 }
5463
5464 #define set_iframe_width(a,b) _set_iframe_width(__LINE__,a,b)
5465 static void _set_iframe_width(unsigned line, IHTMLElement *elem, const char *val)
5466 {
5467     IHTMLIFrameElement2 *iframe = _get_iframe2_iface(line, (IUnknown*)elem);
5468     VARIANT v;
5469     HRESULT hres;
5470
5471     V_VT(&v) = VT_BSTR;
5472     V_BSTR(&v) = a2bstr(val);
5473     hres = IHTMLIFrameElement2_put_width(iframe, v);
5474     ok_(__FILE__,line)(hres == S_OK, "put_width failed: %08x\n", hres);
5475     VariantClear(&v);
5476     IHTMLIFrameElement2_Release(iframe);
5477 }
5478
5479 static void test_iframe_elem(IHTMLElement *elem)
5480 {
5481     IHTMLDocument2 *content_doc, *owner_doc;
5482     IHTMLIFrameElement3 *iframe3;
5483     IHTMLElementCollection *col;
5484     IHTMLWindow2 *content_window;
5485     IHTMLElement *body;
5486     IDispatch *disp;
5487     VARIANT errv;
5488     BSTR str;
5489     HRESULT hres;
5490
5491     static const elem_type_t all_types[] = {
5492         ET_HTML,
5493         ET_HEAD,
5494         ET_TITLE,
5495         ET_BODY,
5496         ET_BR
5497     };
5498
5499     test_frame_doc((IUnknown*)elem, TRUE);
5500     test_framebase((IUnknown*)elem);
5501
5502     content_window = get_frame_content_window((IUnknown*)elem);
5503     test_ifaces((IUnknown*)content_window, window_iids);
5504     test_window_length(content_window, 0);
5505
5506     content_doc = get_window_doc(content_window);
5507     IHTMLWindow2_Release(content_window);
5508
5509     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLIFrameElement3, (void**)&iframe3);
5510     if(SUCCEEDED(hres)) {
5511         hres = IHTMLIFrameElement3_get_contentDocument(iframe3, &disp);
5512         ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
5513         ok(iface_cmp((IUnknown*)content_doc, (IUnknown*)disp), "content_doc != disp\n");
5514         IDispatch_Release(disp);
5515
5516         IHTMLIFrameElement3_Release(iframe3);
5517     }else {
5518         win_skip("IHTMLIFrameElement3 not supported\n");
5519     }
5520
5521     test_iframe_height(elem, NULL);
5522     set_iframe_height(elem, "100px");
5523     set_iframe_height(elem, "50%");
5524     test_iframe_height(elem, "50%");
5525
5526     test_iframe_width(elem, NULL);
5527     set_iframe_width(elem, "150px");
5528     set_iframe_width(elem, "70%");
5529     test_iframe_width(elem, "70%");
5530
5531     str = a2bstr("text/html");
5532     V_VT(&errv) = VT_ERROR;
5533     disp = NULL;
5534     hres = IHTMLDocument2_open(content_doc, str, errv, errv, errv, &disp);
5535     SysFreeString(str);
5536     ok(hres == S_OK, "open failed: %08x\n", hres);
5537     ok(disp != NULL, "disp == NULL\n");
5538     ok(iface_cmp((IUnknown*)disp, (IUnknown*)content_window), "disp != content_window\n");
5539     IDispatch_Release(disp);
5540
5541     doc_write(content_doc, FALSE, "<html><head><title>test</title></head>");
5542     doc_complex_write(content_doc);
5543     doc_write(content_doc, TRUE, "<br />");
5544     doc_write(content_doc, TRUE, "</html>");
5545
5546     hres = IHTMLDocument2_get_all(content_doc, &col);
5547     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5548     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5549     IHTMLElementCollection_Release(col);
5550
5551     body = doc_get_body(content_doc);
5552     test_elem_attr(body, "i4val", "4");
5553     test_elem_attr(body, "r8val", "3.14");
5554     IHTMLElement_Release(body);
5555
5556     hres = IHTMLDocument2_close(content_doc);
5557     ok(hres == S_OK, "close failed: %08x\n", hres);
5558
5559     owner_doc = get_owner_doc((IUnknown*)content_doc);
5560     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
5561
5562     IHTMLDocument2_Release(content_doc);
5563 }
5564
5565 static void test_stylesheet(IDispatch *disp)
5566 {
5567     IHTMLStyleSheetRulesCollection *col = NULL;
5568     IHTMLStyleSheet *stylesheet;
5569     HRESULT hres;
5570
5571     hres = IDispatch_QueryInterface(disp, &IID_IHTMLStyleSheet, (void**)&stylesheet);
5572     ok(hres == S_OK, "Could not get IHTMLStyleSheet: %08x\n", hres);
5573
5574     hres = IHTMLStyleSheet_get_rules(stylesheet, &col);
5575     ok(hres == S_OK, "get_rules failed: %08x\n", hres);
5576     ok(col != NULL, "col == NULL\n");
5577
5578     IHTMLStyleSheetRulesCollection_Release(col);
5579     IHTMLStyleSheet_Release(stylesheet);
5580 }
5581
5582 static void test_stylesheets(IHTMLDocument2 *doc)
5583 {
5584     IHTMLStyleSheetsCollection *col = NULL;
5585     VARIANT idx, res;
5586     LONG len = 0;
5587     HRESULT hres;
5588
5589     hres = IHTMLDocument2_get_styleSheets(doc, &col);
5590     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5591     ok(col != NULL, "col == NULL\n");
5592
5593     test_disp2((IUnknown*)col, &DIID_DispHTMLStyleSheetsCollection, &IID_IHTMLStyleSheetsCollection, "[object]");
5594
5595     hres = IHTMLStyleSheetsCollection_get_length(col, &len);
5596     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5597     ok(len == 1, "len=%d\n", len);
5598
5599     VariantInit(&res);
5600     V_VT(&idx) = VT_I4;
5601     V_I4(&idx) = 0;
5602
5603     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5604     ok(hres == S_OK, "item failed: %08x\n", hres);
5605     ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
5606     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5607     test_stylesheet(V_DISPATCH(&res));
5608     VariantClear(&res);
5609
5610     V_VT(&res) = VT_I4;
5611     V_VT(&idx) = VT_I4;
5612     V_I4(&idx) = 1;
5613
5614     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5615     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5616     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
5617     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5618     VariantClear(&res);
5619
5620     IHTMLStyleSheetsCollection_Release(col);
5621 }
5622
5623 static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
5624 {
5625     IDispatchEx *dispex;
5626     IHTMLDOMNode *node;
5627     DISPPARAMS dp = {NULL, NULL, 0, 0};
5628     VARIANT var;
5629     EXCEPINFO ei;
5630     LONG type;
5631     DISPID id;
5632     BSTR bstr;
5633     HRESULT hres;
5634
5635     static const WCHAR w0[] = {'0',0};
5636     static const WCHAR w100[] = {'1','0','0',0};
5637
5638     hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
5639     ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
5640
5641     bstr = SysAllocString(w0);
5642     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5643     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5644     SysFreeString(bstr);
5645
5646     VariantInit(&var);
5647     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
5648     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
5649     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
5650     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
5651     node = get_node_iface((IUnknown*)V_DISPATCH(&var));
5652     type = get_node_type((IUnknown*)node);
5653     ok(type == 3, "type=%d\n", type);
5654     IHTMLDOMNode_Release(node);
5655     VariantClear(&var);
5656
5657     bstr = SysAllocString(w100);
5658     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5659     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
5660     SysFreeString(bstr);
5661
5662     IDispatchEx_Release(dispex);
5663 }
5664
5665
5666
5667 static void test_elems(IHTMLDocument2 *doc)
5668 {
5669     IHTMLElementCollection *col;
5670     IHTMLDOMChildrenCollection *child_col;
5671     IHTMLElement *elem, *elem2, *elem3;
5672     IHTMLDOMNode *node, *node2;
5673     IHTMLWindow2 *window;
5674     IDispatch *disp;
5675     LONG type;
5676     HRESULT hres;
5677     IHTMLElementCollection *collection;
5678     IHTMLDocument3 *doc3;
5679     BSTR str;
5680
5681     static const elem_type_t all_types[] = {
5682         ET_HTML,
5683         ET_HEAD,
5684         ET_TITLE,
5685         ET_STYLE,
5686         ET_META,
5687         ET_LINK,
5688         ET_BODY,
5689         ET_COMMENT,
5690         ET_A,
5691         ET_INPUT,
5692         ET_SELECT,
5693         ET_OPTION,
5694         ET_OPTION,
5695         ET_TEXTAREA,
5696         ET_TABLE,
5697         ET_TBODY,
5698         ET_TR,
5699         ET_TR,
5700         ET_TD,
5701         ET_TD,
5702         ET_SCRIPT,
5703         ET_TEST,
5704         ET_OBJECT,
5705         ET_EMBED,
5706         ET_IMG,
5707         ET_IFRAME,
5708         ET_FORM,
5709         ET_DIV
5710     };
5711
5712     static const elem_type_t item_types[] = {
5713         ET_A,
5714         ET_OPTION,
5715         ET_TEXTAREA
5716     };
5717
5718     hres = IHTMLDocument2_get_all(doc, &col);
5719     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5720     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5721     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
5722     IHTMLElementCollection_Release(col);
5723
5724     hres = IHTMLDocument2_get_images(doc, &collection);
5725     ok(hres == S_OK, "get_images failed: %08x\n", hres);
5726     if(hres == S_OK)
5727     {
5728         static const elem_type_t images_types[] = {ET_IMG};
5729         test_elem_collection((IUnknown*)collection, images_types, 1);
5730
5731         IHTMLElementCollection_Release(collection);
5732     }
5733
5734     hres = IHTMLDocument2_get_links(doc, &collection);
5735     ok(hres == S_OK, "get_links failed: %08x\n", hres);
5736     if(hres == S_OK)
5737     {
5738         static const elem_type_t images_types[] = {ET_A};
5739         test_elem_collection((IUnknown*)collection, images_types, 1);
5740
5741         IHTMLElementCollection_Release(collection);
5742     }
5743
5744     hres = IHTMLDocument2_get_anchors(doc, &collection);
5745     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5746     if(hres == S_OK)
5747     {
5748         static const elem_type_t anchor_types[] = {ET_A};
5749         test_elem_collection((IUnknown*)collection, anchor_types, 1);
5750
5751         IHTMLElementCollection_Release(collection);
5752     }
5753
5754     test_plugins_col(doc);
5755
5756     elem = get_doc_elem(doc);
5757     test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1);
5758     IHTMLElement_Release(elem);
5759
5760     get_elem_by_id(doc, "xxx", FALSE);
5761     elem = get_doc_elem_by_id(doc, "xxx");
5762     ok(!elem, "elem != NULL\n");
5763
5764     elem = get_doc_elem_by_id(doc, "s");
5765     ok(elem != NULL, "elem == NULL\n");
5766     if(elem) {
5767         test_elem_type((IUnknown*)elem, ET_SELECT);
5768         test_elem_attr(elem, "xxx", NULL);
5769         test_elem_attr(elem, "id", "s");
5770         test_elem_class((IUnknown*)elem, NULL);
5771         test_elem_set_class((IUnknown*)elem, "cl");
5772         test_elem_set_class((IUnknown*)elem, NULL);
5773         test_elem_tabindex((IUnknown*)elem, 0);
5774         test_elem_set_tabindex((IUnknown*)elem, 1);
5775         test_elem_filters((IUnknown*)elem);
5776
5777         node = test_node_get_parent((IUnknown*)elem);
5778         ok(node != NULL, "node == NULL\n");
5779         test_node_name((IUnknown*)node, "BODY");
5780         node2 = test_node_get_parent((IUnknown*)node);
5781         IHTMLDOMNode_Release(node);
5782         ok(node2 != NULL, "node == NULL\n");
5783         test_node_name((IUnknown*)node2, "HTML");
5784         node = test_node_get_parent((IUnknown*)node2);
5785         IHTMLDOMNode_Release(node2);
5786         ok(node != NULL, "node == NULL\n");
5787         if (node)
5788         {
5789             test_node_name((IUnknown*)node, "#document");
5790             type = get_node_type((IUnknown*)node);
5791             ok(type == 9, "type=%d, expected 9\n", type);
5792             node2 = test_node_get_parent((IUnknown*)node);
5793             IHTMLDOMNode_Release(node);
5794             ok(node2 == NULL, "node != NULL\n");
5795         }
5796
5797         elem2 = test_elem_get_parent((IUnknown*)elem);
5798         ok(elem2 != NULL, "elem2 == NULL\n");
5799         test_node_name((IUnknown*)elem2, "BODY");
5800
5801         elem3 = test_elem_get_parent((IUnknown*)elem2);
5802         ok(elem3 != NULL, "elem3 == NULL\n");
5803         test_node_name((IUnknown*)elem3, "HTML");
5804
5805         test_elem_contains(elem3, elem2, VARIANT_TRUE);
5806         test_elem_contains(elem3, elem, VARIANT_TRUE);
5807         test_elem_contains(elem2, elem, VARIANT_TRUE);
5808         test_elem_contains(elem2, elem3, VARIANT_FALSE);
5809         test_elem_contains(elem, elem3, VARIANT_FALSE);
5810         test_elem_contains(elem, elem2, VARIANT_FALSE);
5811         test_elem_contains(elem, elem, VARIANT_TRUE);
5812         IHTMLElement_Release(elem2);
5813
5814         elem2 = test_elem_get_parent((IUnknown*)elem3);
5815         ok(elem2 == NULL, "elem2 != NULL\n");
5816         IHTMLElement_Release(elem3);
5817
5818         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2, NULL);
5819         test_elem_getelembytag((IUnknown*)elem, ET_SELECT, 0, NULL);
5820         test_elem_getelembytag((IUnknown*)elem, ET_HTML, 0, NULL);
5821
5822         test_elem_innertext(elem, "opt1opt2");
5823
5824         IHTMLElement_Release(elem);
5825     }
5826
5827     elem = get_elem_by_id(doc, "s", TRUE);
5828     if(elem) {
5829         IHTMLSelectElement *select = get_select_iface((IUnknown*)elem);
5830         IHTMLDocument2 *doc_node, *elem_doc;
5831
5832         test_select_elem(select);
5833
5834         test_elem_title((IUnknown*)select, NULL);
5835         test_elem_set_title((IUnknown*)select, "Title");
5836         test_elem_title((IUnknown*)select, "Title");
5837         test_elem_offset((IUnknown*)select, "BODY");
5838         test_elem_bounding_client_rect((IUnknown*)select);
5839
5840         node = get_first_child((IUnknown*)select);
5841         ok(node != NULL, "node == NULL\n");
5842         if(node) {
5843             test_elem_type((IUnknown*)node, ET_OPTION);
5844             IHTMLDOMNode_Release(node);
5845         }
5846
5847         type = get_node_type((IUnknown*)select);
5848         ok(type == 1, "type=%d\n", type);
5849
5850         IHTMLSelectElement_Release(select);
5851
5852         elem_doc = get_elem_doc((IUnknown*)elem);
5853
5854         doc_node = get_doc_node(doc);
5855         ok(iface_cmp((IUnknown*)elem_doc, (IUnknown*)doc_node), "disp != doc\n");
5856         IHTMLDocument2_Release(doc_node);
5857         IHTMLDocument2_Release(elem_doc);
5858
5859         IHTMLElement_Release(elem);
5860     }
5861
5862     elem = get_elem_by_id(doc, "sc", TRUE);
5863     if(elem) {
5864         IHTMLScriptElement *script;
5865         BSTR type;
5866
5867         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLScriptElement, (void**)&script);
5868         ok(hres == S_OK, "Could not get IHTMLScriptElement interface: %08x\n", hres);
5869
5870         if(hres == S_OK)
5871         {
5872             VARIANT_BOOL vb;
5873
5874             hres = IHTMLScriptElement_put_type (script, NULL);
5875             ok(hres == S_OK, "put_type failed: %08x\n", hres);
5876             hres = IHTMLScriptElement_get_type(script, &type);
5877             ok(hres == S_OK, "get_type failed: %08x\n", hres);
5878             ok(type == NULL, "Unexpected type %s\n", wine_dbgstr_w(type));
5879
5880             hres = IHTMLScriptElement_put_type (script, a2bstr ("text/javascript"));
5881             ok(hres == S_OK, "put_type failed: %08x\n", hres);
5882             hres = IHTMLScriptElement_get_type(script, &type);
5883             ok(hres == S_OK, "get_type failed: %08x\n", hres);
5884             ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type));
5885             SysFreeString(type);
5886
5887             test_script_text(script, "<!--\nfunction Testing() {}\n// -->\n");
5888
5889             /* test defer */
5890             hres = IHTMLScriptElement_put_defer(script, VARIANT_TRUE);
5891             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5892
5893             hres = IHTMLScriptElement_get_defer(script, &vb);
5894             ok(hres == S_OK, "get_defer failed: %08x\n", hres);
5895             ok(vb == VARIANT_TRUE, "get_defer result is %08x\n", hres);
5896
5897             hres = IHTMLScriptElement_put_defer(script, VARIANT_FALSE);
5898             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5899
5900             str = (BSTR)0xdeadbeef;
5901             hres = IHTMLScriptElement_get_src(script, &str);
5902             ok(hres == S_OK, "get_src failed: %08x\n", hres);
5903             ok(!str, "src = %s\n", wine_dbgstr_w(str));
5904         }
5905
5906         IHTMLScriptElement_Release(script);
5907     }
5908
5909     elem = get_elem_by_id(doc, "in", TRUE);
5910     if(elem) {
5911         IHTMLInputElement *input;
5912
5913         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLInputElement, (void**)&input);
5914         ok(hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
5915
5916         test_elem_id((IUnknown*)elem, "in");
5917         test_elem_put_id((IUnknown*)elem, "newin");
5918         test_input_get_disabled(input, VARIANT_FALSE);
5919         test_input_set_disabled(input, VARIANT_TRUE);
5920         test_input_set_disabled(input, VARIANT_FALSE);
5921         test_elem3_set_disabled((IUnknown*)input, VARIANT_TRUE);
5922         test_input_get_disabled(input, VARIANT_TRUE);
5923         test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE);
5924         test_input_get_disabled(input, VARIANT_FALSE);
5925         test_elem_client_size((IUnknown*)elem);
5926         test_input_type(input, "text");
5927
5928         test_node_get_value_str((IUnknown*)elem, NULL);
5929         test_node_put_value_str((IUnknown*)elem, "test");
5930         test_node_get_value_str((IUnknown*)elem, NULL);
5931         test_input_value((IUnknown*)elem, NULL);
5932         test_input_defaultValue((IUnknown*)elem, NULL);
5933         test_input_put_value((IUnknown*)elem, "test");
5934         test_input_defaultValue((IUnknown*)elem, NULL);
5935         test_elem_class((IUnknown*)elem, "testclass");
5936         test_elem_tabindex((IUnknown*)elem, 2);
5937         test_elem_set_tabindex((IUnknown*)elem, 3);
5938         test_elem_title((IUnknown*)elem, "test title");
5939
5940         test_input_get_defaultchecked(input, VARIANT_FALSE);
5941         test_input_set_defaultchecked(input, VARIANT_TRUE);
5942         test_input_set_defaultchecked(input, VARIANT_FALSE);
5943
5944         test_input_get_checked(input, VARIANT_FALSE);
5945         test_input_set_checked(input, VARIANT_TRUE);
5946         test_input_set_checked(input, VARIANT_FALSE);
5947
5948         test_input_maxlength(input, 0x7fffffff);
5949         test_input_set_maxlength(input, 30);
5950
5951         test_input_name(input, NULL);
5952         test_input_set_name(input, "test");
5953
5954         test_input_src(input, NULL);
5955         test_input_set_src(input, "about:blank");
5956
5957         IHTMLInputElement_Release(input);
5958         IHTMLElement_Release(elem);
5959     }
5960
5961     elem = get_elem_by_id(doc, "imgid", TRUE);
5962     if(elem) {
5963         test_img_src((IUnknown*)elem, "", NULL);
5964         test_img_set_src((IUnknown*)elem, "about:blank");
5965         test_img_src((IUnknown*)elem, "about:blank", NULL);
5966         test_img_alt((IUnknown*)elem, NULL);
5967         test_img_set_alt((IUnknown*)elem, "alt test");
5968         test_img_name((IUnknown*)elem, "WineImg");
5969         test_img_complete(elem, VARIANT_FALSE);
5970         IHTMLElement_Release(elem);
5971     }
5972
5973     elem = get_elem_by_id(doc, "attr", TRUE);
5974     if(elem) {
5975         test_dynamic_properties(elem);
5976         test_attr_collection(elem);
5977         IHTMLElement_Release(elem);
5978     }
5979
5980     elem = get_elem_by_id(doc, "styleid", TRUE);
5981     if(elem) {
5982         test_style_media((IUnknown*)elem, NULL);
5983         test_style_put_media((IUnknown*)elem, "screen");
5984         test_style_type((IUnknown*)elem, NULL);
5985         test_style_put_type((IUnknown*)elem, "text/css");
5986         IHTMLElement_Release(elem);
5987     }
5988
5989     elem = get_doc_elem_by_id(doc, "tbl");
5990     ok(elem != NULL, "elem == NULL\n");
5991     if(elem) {
5992         test_table_elem(elem);
5993         IHTMLElement_Release(elem);
5994     }
5995
5996     elem = get_doc_elem_by_id(doc, "row2");
5997     ok(elem != NULL, "elem == NULL\n");
5998     if(elem) {
5999         test_tr_elem(elem);
6000         IHTMLElement_Release(elem);
6001     }
6002
6003     elem = get_doc_elem_by_id(doc, "ifr");
6004     ok(elem != NULL, "elem == NULL\n");
6005     if(elem) {
6006         test_iframe_elem(elem);
6007         IHTMLElement_Release(elem);
6008     }
6009
6010     elem = get_doc_elem_by_id(doc, "objid");
6011     ok(elem != NULL, "elem == NULL\n");
6012     if(elem) {
6013         test_object_vspace((IUnknown*)elem, 100);
6014         test_object_name(elem, "objname");
6015         set_object_name(elem, "test");
6016         set_object_name(elem, NULL);
6017         IHTMLElement_Release(elem);
6018     }
6019
6020     elem = get_elem_by_id(doc, "a", TRUE);
6021     if(elem) {
6022         test_anchor_href((IUnknown*)elem, "http://test/");
6023
6024         /* Change the href */
6025         test_anchor_put_href((IUnknown*)elem, "http://test1/");
6026         test_anchor_href((IUnknown*)elem, "http://test1/");
6027
6028         /* Restore the href */
6029         test_anchor_put_href((IUnknown*)elem, "http://test/");
6030         test_anchor_href((IUnknown*)elem, "http://test/");
6031
6032         /* target */
6033         test_anchor_get_target((IUnknown*)elem, NULL);
6034
6035         /* Change the target */
6036         test_anchor_put_target((IUnknown*)elem, "wine");
6037         test_anchor_get_target((IUnknown*)elem, "wine");
6038
6039         /* Restore the target */
6040         test_anchor_put_target((IUnknown*)elem, NULL);
6041         test_anchor_get_target((IUnknown*)elem, NULL);
6042
6043         test_anchor_name((IUnknown*)elem, "x");
6044         test_anchor_put_name((IUnknown*)elem, "anchor name");
6045         test_anchor_put_name((IUnknown*)elem, NULL);
6046         test_anchor_put_name((IUnknown*)elem, "x");
6047
6048         IHTMLElement_Release(elem);
6049     }
6050
6051     elem = get_doc_elem_by_id(doc, "metaid");
6052     if(elem) {
6053         test_meta_name((IUnknown*)elem, "meta name");
6054         test_meta_content((IUnknown*)elem, "text/html; charset=utf-8");
6055         test_meta_httpequiv((IUnknown*)elem, "Content-Type");
6056         IHTMLElement_Release(elem);
6057     }
6058
6059     elem = doc_get_body(doc);
6060
6061     node = get_first_child((IUnknown*)elem);
6062     ok(node != NULL, "node == NULL\n");
6063     if(node) {
6064         test_ifaces((IUnknown*)node, text_iids);
6065         test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
6066
6067         node2 = get_first_child((IUnknown*)node);
6068         ok(!node2, "node2 != NULL\n");
6069
6070         type = get_node_type((IUnknown*)node);
6071         ok(type == 3, "type=%d\n", type);
6072
6073         test_node_get_value_str((IUnknown*)node, "text test");
6074         test_node_put_value_str((IUnknown*)elem, "test text");
6075         test_node_get_value_str((IUnknown*)node, "text test");
6076
6077         hres = IHTMLDOMNode_get_attributes(node, &disp);
6078         ok(hres == S_OK, "get_attributes failed: %08x\n", hres);
6079         ok(!disp, "disp != NULL\n");
6080
6081         IHTMLDOMNode_Release(node);
6082     }
6083
6084     child_col = get_child_nodes((IUnknown*)elem);
6085     ok(child_col != NULL, "child_coll == NULL\n");
6086     if(child_col) {
6087         LONG length = 0;
6088
6089         test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]");
6090
6091         hres = IHTMLDOMChildrenCollection_get_length(child_col, &length);
6092         ok(hres == S_OK, "get_length failed: %08x\n", hres);
6093         ok(length, "length=0\n");
6094
6095         node2 = NULL;
6096         node = get_child_item(child_col, 0);
6097         ok(node != NULL, "node == NULL\n");
6098         if(node) {
6099             IHTMLDOMNode *prev;
6100
6101             type = get_node_type((IUnknown*)node);
6102             ok(type == 3, "type=%d\n", type);
6103             node2 = node_get_next((IUnknown*)node);
6104
6105             prev = node_get_prev((IUnknown*)node2);
6106             ok(iface_cmp((IUnknown*)node, (IUnknown*)prev), "node != prev\n");
6107             IHTMLDOMNode_Release(prev);
6108
6109             IHTMLDOMNode_Release(node);
6110         }
6111
6112         node = get_child_item(child_col, 1);
6113         ok(node != NULL, "node == NULL\n");
6114         if(node) {
6115             type = get_node_type((IUnknown*)node);
6116             ok(type == 8, "type=%d\n", type);
6117
6118             test_elem_id((IUnknown*)node, NULL);
6119             ok(iface_cmp((IUnknown*)node2, (IUnknown*)node), "node2 != node\n");
6120             IHTMLDOMNode_Release(node2);
6121             IHTMLDOMNode_Release(node);
6122         }
6123
6124         hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL);
6125         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
6126
6127         hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL);
6128         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
6129
6130         hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp);
6131         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
6132
6133         hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp);
6134         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
6135
6136         test_child_col_disp(child_col);
6137
6138         IHTMLDOMChildrenCollection_Release(child_col);
6139     }
6140
6141     test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
6142     test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
6143     test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
6144
6145     IHTMLElement_Release(elem);
6146
6147     elem = get_doc_elem_by_id(doc, "frm");
6148     ok(elem != NULL, "elem == NULL\n");
6149     if(elem) {
6150         test_form_length((IUnknown*)elem, 0);
6151         test_form_elements((IUnknown*)elem);
6152         IHTMLElement_Release(elem);
6153     }
6154
6155     test_stylesheets(doc);
6156     test_create_option_elem(doc);
6157     test_create_img_elem(doc);
6158
6159     elem = get_doc_elem_by_id(doc, "tbl");
6160     ok(elem != NULL, "elem = NULL\n");
6161     test_elem_set_innertext(elem, "inner text");
6162     IHTMLElement_Release(elem);
6163
6164     test_doc_title(doc, "test");
6165     test_doc_set_title(doc, "test title");
6166     test_doc_title(doc, "test title");
6167
6168     disp = NULL;
6169     hres = IHTMLDocument2_get_Script(doc, &disp);
6170     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
6171     if(hres == S_OK)
6172     {
6173         IDispatchEx *dispex;
6174         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
6175         ok(hres == S_OK, "IDispatch_QueryInterface failed: %08x\n", hres);
6176         if(hres == S_OK)
6177         {
6178             DISPID pid = -1;
6179             BSTR str = a2bstr("Testing");
6180             hres = IDispatchEx_GetDispID(dispex, str, 1, &pid);
6181             ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
6182             ok(pid != -1, "pid == -1\n");
6183             SysFreeString(str);
6184             IDispatchEx_Release(dispex);
6185         }
6186     }
6187     IDispatch_Release(disp);
6188
6189     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
6190     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
6191
6192     str = a2bstr("img");
6193     hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col);
6194     ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres);
6195     SysFreeString(str);
6196     if(hres == S_OK)
6197     {
6198         static const elem_type_t img_types[] = { ET_IMG };
6199
6200         test_elem_collection((IUnknown*)col, img_types, sizeof(img_types)/sizeof(img_types[0]));
6201         IHTMLElementCollection_Release(col);
6202     }
6203
6204     elem = get_doc_elem_by_id(doc, "y");
6205     test_elem_set_innerhtml((IUnknown*)elem, "inner html");
6206     test_elem_innerhtml((IUnknown*)elem, "inner html");
6207     test_elem_set_innerhtml((IUnknown*)elem, "");
6208     test_elem_innerhtml((IUnknown*)elem, NULL);
6209     node = node_get_next((IUnknown*)elem);
6210     ok(!node, "node = %p\n", node);
6211
6212     elem2 = get_doc_elem_by_id(doc, "x");
6213     test_elem_tag((IUnknown*)elem2, "A");
6214     node = node_get_next((IUnknown*)elem2);
6215     IHTMLDOMNode_Release(node);
6216     IHTMLElement_Release(elem2);
6217     IHTMLElement_Release(elem);
6218
6219     IHTMLDocument3_Release(doc3);
6220
6221     elem = get_elem_by_id(doc, "s", TRUE);
6222     if(elem) {
6223         static const elem_type_t select_types[] = { ET_OPTION, ET_OPTION, ET_OPTION };
6224
6225         test_select_put_length((IUnknown*)elem, 3);
6226         test_elem_all((IUnknown*)elem, select_types, sizeof(select_types)/sizeof(*select_types));
6227         test_select_put_length((IUnknown*)elem, 1);
6228         test_elem_all((IUnknown*)elem, select_types, 1);
6229         IHTMLElement_Release(elem);
6230     }
6231
6232     window = get_doc_window(doc);
6233     test_window_name(window, NULL);
6234     set_window_name(window, "test name");
6235     test_window_length(window, 1);
6236     IHTMLWindow2_Release(window);
6237 }
6238
6239 static void test_attr(IHTMLElement *elem)
6240 {
6241     IHTMLDOMAttribute *attr, *attr2;
6242     VARIANT v;
6243
6244     get_elem_attr_node((IUnknown*)elem, "noattr", FALSE);
6245
6246     attr = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
6247
6248     test_disp((IUnknown*)attr, &DIID_DispHTMLDOMAttribute, "[object]");
6249     test_ifaces((IUnknown*)attr, attr_iids);
6250     test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
6251     test_attr_specified(attr, VARIANT_TRUE);
6252
6253     attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
6254     ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");
6255     IHTMLDOMAttribute_Release(attr2);
6256
6257     get_attr_node_value(attr, &v, VT_BSTR);
6258     ok(!strcmp_wa(V_BSTR(&v), "divid"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
6259     VariantClear(&v);
6260
6261     IHTMLDOMAttribute_Release(attr);
6262
6263     attr = get_elem_attr_node((IUnknown*)elem, "emptyattr", TRUE);
6264     get_attr_node_value(attr, &v, VT_BSTR);
6265     ok(!V_BSTR(&v), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
6266     VariantClear(&v);
6267     test_attr_specified(attr, VARIANT_TRUE);
6268     IHTMLDOMAttribute_Release(attr);
6269
6270     V_VT(&v) = VT_I4;
6271     V_I4(&v) = 100;
6272     set_dispex_value((IUnknown*)elem, "dispprop", &v);
6273     attr = get_elem_attr_node((IUnknown*)elem, "dispprop", TRUE);
6274     get_attr_node_value(attr, &v, VT_I4);
6275     ok(V_I4(&v) == 100, "V_I4(v) = %d\n", V_I4(&v));
6276     test_attr_specified(attr, VARIANT_TRUE);
6277     IHTMLDOMAttribute_Release(attr);
6278
6279     attr = get_elem_attr_node((IUnknown*)elem, "tabIndex", TRUE);
6280     test_attr_specified(attr, VARIANT_FALSE);
6281     IHTMLDOMAttribute_Release(attr);
6282 }
6283
6284 static void test_blocked(IHTMLDocument2 *doc, IHTMLElement *outer_elem)
6285 {
6286     IHTMLElement *elem;
6287
6288     test_elem_set_innerhtml((IUnknown*)outer_elem,
6289             "<img id=\"imgid\" src=\"BLOCKED::http://www.winehq.org/img.png\" />");
6290     elem = get_elem_by_id(doc, "imgid", TRUE);
6291     if(elem) {
6292         test_img_src((IUnknown*)elem, "BLOCKED::", "blocked::http://www.winehq.org/img.png");
6293         IHTMLElement_Release(elem);
6294     }
6295
6296     test_elem_set_innerhtml((IUnknown*)outer_elem,
6297             "<img id=\"imgid\" src=\"BLOCKE::http://www.winehq.org/img.png\" />");
6298     elem = get_elem_by_id(doc, "imgid", TRUE);
6299     if(elem) {
6300         test_img_src((IUnknown*)elem, "blocke::http://www.winehq.org/img.png", NULL);
6301         test_img_set_src((IUnknown*)elem, "BLOCKED:http://www.winehq.org/img.png");
6302         test_img_src((IUnknown*)elem, "blocked:http://www.winehq.org/img.png", NULL);
6303         test_img_set_src((IUnknown*)elem, "blocked::http://www.winehq.org/img.png");
6304         test_img_src((IUnknown*)elem, "BLOCKED::", "blocked::http://www.winehq.org/img.png");
6305         IHTMLElement_Release(elem);
6306     }
6307 }
6308
6309 static void test_elems2(IHTMLDocument2 *doc)
6310 {
6311     IHTMLElement *elem, *elem2, *div;
6312
6313     static const elem_type_t outer_types[] = {
6314         ET_BR,
6315         ET_A
6316     };
6317
6318     div = get_doc_elem_by_id(doc, "divid");
6319
6320     elem = get_elem_by_id(doc, "linkid", TRUE);
6321     if(elem) {
6322         test_link_disabled(elem, VARIANT_FALSE);
6323         test_link_rel(elem, "stylesheet");
6324         test_link_type(elem, "text/css");
6325         test_link_href(elem, "about:blank");
6326         link_put_disabled(elem, VARIANT_TRUE);
6327         link_put_rel(elem, "prev");
6328         link_put_type(elem, "text/plain");
6329         link_put_href(elem, "about:prev");
6330         IHTMLElement_Release(elem);
6331     }
6332
6333     test_elem_set_innerhtml((IUnknown*)div, "<div id=\"innerid\"></div>");
6334     elem2 = get_doc_elem_by_id(doc, "innerid");
6335     ok(elem2 != NULL, "elem2 == NULL\n");
6336     test_elem_set_outerhtml((IUnknown*)elem2, "<br><a href=\"about:blank\" id=\"aid\">a</a>");
6337     test_elem_all((IUnknown*)div, outer_types, sizeof(outer_types)/sizeof(*outer_types));
6338     IHTMLElement_Release(elem2);
6339
6340     elem2 = get_doc_elem_by_id(doc, "aid");
6341     ok(elem2 != NULL, "elem2 == NULL\n");
6342     test_elem_set_outerhtml((IUnknown*)elem2, "");
6343     test_elem_all((IUnknown*)div, outer_types, 1);
6344     IHTMLElement_Release(elem2);
6345
6346     test_elem_set_innerhtml((IUnknown*)div, "<textarea id=\"ta\"></textarea>");
6347     elem = get_elem_by_id(doc, "ta", TRUE);
6348     if(elem) {
6349         test_textarea_value((IUnknown*)elem, NULL);
6350         test_textarea_put_value((IUnknown*)elem, "test");
6351         test_textarea_readonly((IUnknown*)elem, VARIANT_FALSE);
6352         test_textarea_put_readonly((IUnknown*)elem, VARIANT_TRUE);
6353         test_textarea_put_readonly((IUnknown*)elem, VARIANT_FALSE);
6354         test_textarea_type((IUnknown*)elem);
6355         IHTMLElement_Release(elem);
6356     }
6357
6358     test_elem_set_innerhtml((IUnknown*)div,
6359             "<input value=\"val\" id =\"inputid\"  />");
6360     elem = get_elem_by_id(doc, "inputid", TRUE);
6361     if(elem) {
6362         test_input_defaultValue((IUnknown*)elem, "val");
6363         test_input_put_value((IUnknown*)elem, "test");
6364         test_input_put_defaultValue((IUnknown*)elem, "new val");
6365         test_input_value((IUnknown*)elem, "test");
6366         IHTMLElement_Release(elem);
6367     }
6368
6369     test_elem_set_innerhtml((IUnknown*)div,
6370             "<form id=\"form\"><input type=\"button\" /><div><input type=\"text\" /></div></textarea>");
6371     elem = get_elem_by_id(doc, "form", TRUE);
6372     if(elem) {
6373         test_form_length((IUnknown*)elem, 2);
6374         test_form_item(elem);
6375         test_form_action((IUnknown*)elem, NULL);
6376         test_form_put_action((IUnknown*)elem, "about:blank");
6377         test_form_method((IUnknown*)elem, "get");
6378         test_form_put_method((IUnknown*)elem, S_OK, "post");
6379         test_form_put_method((IUnknown*)elem, E_INVALIDARG, "put");
6380         test_form_method((IUnknown*)elem, "post");
6381         test_form_name((IUnknown*)elem, NULL);
6382         test_form_put_name((IUnknown*)elem, "Name");
6383         test_form_encoding((IUnknown*)elem, "application/x-www-form-urlencoded");
6384         test_form_put_encoding((IUnknown*)elem, S_OK, "text/plain");
6385         test_form_put_encoding((IUnknown*)elem, S_OK, "multipart/form-data");
6386         test_form_put_encoding((IUnknown*)elem, E_INVALIDARG, "image/png");
6387         test_form_encoding((IUnknown*)elem, "multipart/form-data");
6388         test_form_elements((IUnknown*)elem);
6389         IHTMLElement_Release(elem);
6390     }
6391
6392     test_attr(div);
6393     test_blocked(doc, div);
6394
6395     IHTMLElement_Release(div);
6396 }
6397
6398 static void test_create_elems(IHTMLDocument2 *doc)
6399 {
6400     IHTMLElement *elem, *body, *elem2;
6401     IHTMLDOMNode *node, *node2, *node3, *comment;
6402     IHTMLDocument5 *doc5;
6403     IDispatch *disp;
6404     VARIANT var;
6405     LONG type;
6406     HRESULT hres;
6407     BSTR str;
6408
6409     static const elem_type_t types1[] = { ET_TESTG };
6410
6411     elem = test_create_elem(doc, "TEST");
6412     test_elem_tag((IUnknown*)elem, "TEST");
6413     type = get_node_type((IUnknown*)elem);
6414     ok(type == 1, "type=%d\n", type);
6415     test_ifaces((IUnknown*)elem, elem_iids);
6416     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
6417
6418     body = doc_get_body(doc);
6419     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
6420
6421     node = test_node_append_child((IUnknown*)body, (IUnknown*)elem);
6422     test_node_has_child((IUnknown*)body, VARIANT_TRUE);
6423     elem2 = get_elem_iface((IUnknown*)node);
6424     IHTMLElement_Release(elem2);
6425
6426     hres = IHTMLElement_get_all(body, &disp);
6427     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6428     test_elem_collection((IUnknown*)disp, types1, sizeof(types1)/sizeof(types1[0]));
6429     IDispatch_Release(disp);
6430
6431     test_node_remove_child((IUnknown*)body, node);
6432
6433     hres = IHTMLElement_get_all(body, &disp);
6434     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6435     test_elem_collection((IUnknown*)disp, NULL, 0);
6436     IDispatch_Release(disp);
6437     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
6438
6439     IHTMLElement_Release(elem);
6440     IHTMLDOMNode_Release(node);
6441
6442     node = test_create_text(doc, "test");
6443     test_ifaces((IUnknown*)node, text_iids);
6444     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
6445     test_text_length((IUnknown*)node, 4);
6446
6447     V_VT(&var) = VT_NULL;
6448     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
6449     IHTMLDOMNode_Release(node);
6450
6451     node = test_create_text(doc, "insert ");
6452
6453     V_VT(&var) = VT_DISPATCH;
6454     V_DISPATCH(&var) = (IDispatch*)node2;
6455     node3 = test_node_insertbefore((IUnknown*)body, node, &var);
6456     IHTMLDOMNode_Release(node);
6457     IHTMLDOMNode_Release(node2);
6458     IHTMLDOMNode_Release(node3);
6459
6460     test_elem_innertext(body, "insert test");
6461     test_elem_innerhtml((IUnknown*)body, "insert test");
6462
6463     node = test_create_text(doc, " Test");
6464     V_VT(&var) = VT_DISPATCH;
6465     V_DISPATCH(&var) = NULL;
6466     test_node_insertbefore((IUnknown*)body, node, &var);
6467     test_elem_innertext(body, "insert test Test");
6468     IHTMLDOMNode_Release(node);
6469
6470     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
6471     if(hres == S_OK)
6472     {
6473         str = a2bstr("testing");
6474         hres = IHTMLDocument5_createComment(doc5, str, &comment);
6475         SysFreeString(str);
6476         ok(hres == S_OK, "createComment failed: %08x\n", hres);
6477         if(hres == S_OK)
6478         {
6479             type = get_node_type((IUnknown*)comment);
6480             ok(type == 8, "type=%d, expected 8\n", type);
6481
6482             test_node_get_value_str((IUnknown*)comment, "testing");
6483             test_elem_title((IUnknown*)comment, NULL);
6484             test_elem_set_title((IUnknown*)comment, "comment title");
6485             test_elem_title((IUnknown*)comment, "comment title");
6486             test_comment_text((IUnknown*)comment, "<!--testing-->");
6487             test_elem_outerhtml((IUnknown*)comment, "<!--testing-->");
6488             test_comment_attrs((IUnknown*)comment);
6489
6490             IHTMLDOMNode_Release(comment);
6491         }
6492
6493         IHTMLDocument5_Release(doc5);
6494     }
6495
6496     IHTMLElement_Release(body);
6497 }
6498
6499 static void test_replacechild_elems(IHTMLDocument2 *doc)
6500 {
6501     IHTMLElement *body;
6502     IHTMLDOMNode *node, *node2, *node3;
6503     IHTMLDOMNode *nodeBody, *nodeNew;
6504     HRESULT hres;
6505     VARIANT var;
6506
6507     body = doc_get_body(doc);
6508
6509     node = test_create_text(doc, "insert");
6510
6511     V_VT(&var) = VT_NULL;
6512     V_DISPATCH(&var) = NULL;
6513     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
6514     IHTMLDOMNode_Release(node);
6515
6516     test_elem_innertext(body, "insert");
6517
6518     node3 = test_create_text(doc, "replaced");
6519
6520     nodeBody = _get_node_iface(__LINE__, (IUnknown *)body);
6521
6522     hres = IHTMLDOMNode_replaceChild(nodeBody, node3, node2, &nodeNew);
6523     ok(hres == S_OK, "Expected S_OK, got 0x%08x\n", hres);
6524
6525     test_elem_innertext(body, "replaced");
6526
6527     IHTMLDOMNode_Release(node2);
6528     IHTMLDOMNode_Release(node3);
6529     IHTMLDOMNode_Release(nodeBody);
6530
6531     IHTMLElement_Release(body);
6532 }
6533
6534 static void test_noscript(IHTMLDocument2 *doc)
6535 {
6536     IHTMLElementCollection *col;
6537     IHTMLElement *body;
6538     HRESULT hres;
6539
6540     static const elem_type_t all_types[] = {
6541         ET_HTML,
6542         ET_HEAD,
6543         ET_TITLE,
6544         ET_NOSCRIPT,
6545         ET_BODY,
6546         ET_NOSCRIPT
6547     };
6548
6549     static const elem_type_t body_all_types[] = {
6550         ET_DIV,
6551         ET_NOSCRIPT
6552     };
6553
6554     hres = IHTMLDocument2_get_all(doc, &col);
6555     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6556     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6557     IHTMLElementCollection_Release(col);
6558
6559     body = doc_get_body(doc);
6560     test_elem_set_innerhtml((IUnknown*)body, "<div>test</div><noscript><a href=\"about:blank\">A</a></noscript>");
6561     test_elem_all((IUnknown*)body, body_all_types, sizeof(body_all_types)/sizeof(*body_all_types));
6562     IHTMLElement_Release(body);
6563 }
6564
6565 static void test_doctype(IHTMLDocument2 *doc)
6566 {
6567     IHTMLDocument2 *doc_node;
6568     IHTMLDOMNode *doctype;
6569     int type;
6570
6571     doc_node = get_doc_node(doc);
6572     doctype = get_first_child((IUnknown*)doc_node);
6573     IHTMLDocument2_Release(doc_node);
6574
6575     type = get_node_type((IUnknown*)doctype);
6576     ok(type == 8, "type = %d\n", type);
6577
6578     test_comment_text((IUnknown*)doctype, "<!DOCTYPE html>");
6579     test_elem_type((IUnknown*)doctype, ET_COMMENT);
6580     IHTMLDOMNode_Release(doctype);
6581 }
6582
6583 static void test_null_write(IHTMLDocument2 *doc)
6584 {
6585     HRESULT hres;
6586
6587     doc_write(doc, FALSE, NULL);
6588     doc_write(doc, TRUE, NULL);
6589
6590     hres = IHTMLDocument2_write(doc, NULL);
6591     ok(hres == S_OK,
6592        "Expected IHTMLDocument2::write to return S_OK, got 0x%08x\n", hres);
6593
6594     hres = IHTMLDocument2_writeln(doc, NULL);
6595     ok(hres == S_OK,
6596        "Expected IHTMLDocument2::writeln to return S_OK, got 0x%08x\n", hres);
6597 }
6598
6599 static void test_create_stylesheet(IHTMLDocument2 *doc)
6600 {
6601     IHTMLStyleSheet *stylesheet, *stylesheet2;
6602     IHTMLStyleElement *style_elem;
6603     IHTMLElement *doc_elem, *elem;
6604     HRESULT hres;
6605
6606     static const elem_type_t all_types[] = {
6607         ET_HTML,
6608         ET_HEAD,
6609         ET_TITLE,
6610         ET_BODY,
6611         ET_DIV
6612     };
6613
6614     static const elem_type_t all_types2[] = {
6615         ET_HTML,
6616         ET_HEAD,
6617         ET_TITLE,
6618         ET_STYLE,
6619         ET_BODY,
6620         ET_DIV
6621     };
6622
6623     test_doc_all(doc, all_types, sizeof(all_types)/sizeof(*all_types));
6624
6625     hres = IHTMLDocument2_createStyleSheet(doc, NULL, -1, &stylesheet);
6626     ok(hres == S_OK, "createStyleSheet failed: %08x\n", hres);
6627
6628     test_doc_all(doc, all_types2, sizeof(all_types2)/sizeof(*all_types2));
6629
6630     doc_elem = get_doc_elem(doc);
6631
6632     test_elem_getelembytag((IUnknown*)doc_elem, ET_STYLE, 1, &elem);
6633     IHTMLElement_Release(doc_elem);
6634
6635     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLStyleElement, (void**)&style_elem);
6636     IHTMLElement_Release(elem);
6637     ok(hres == S_OK, "Could not get IHTMLStyleElement iface: %08x\n", hres);
6638
6639     stylesheet2 = NULL;
6640     hres = IHTMLStyleElement_get_styleSheet(style_elem, &stylesheet2);
6641     ok(hres == S_OK, "get_styleSheet failed: %08x\n", hres);
6642     ok(stylesheet2 != NULL, "stylesheet2 == NULL\n");
6643     ok(iface_cmp((IUnknown*)stylesheet, (IUnknown*)stylesheet2), "stylesheet != stylesheet2\n");
6644
6645     IHTMLStyleSheet_Release(stylesheet2);
6646     IHTMLStyleSheet_Release(stylesheet);
6647
6648     IHTMLStyleElement_Release(style_elem);
6649 }
6650
6651 static void test_exec(IUnknown *unk, const GUID *grpid, DWORD cmdid, VARIANT *in, VARIANT *out)
6652 {
6653     IOleCommandTarget *cmdtrg;
6654     HRESULT hres;
6655
6656     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
6657     ok(hres == S_OK, "Could not get IOleCommandTarget interface: %08x\n", hres);
6658
6659     hres = IOleCommandTarget_Exec(cmdtrg, grpid, cmdid, 0, in, out);
6660     ok(hres == S_OK, "Exec failed: %08x\n", hres);
6661
6662     IOleCommandTarget_Release(cmdtrg);
6663 }
6664
6665 static void test_indent(IHTMLDocument2 *doc)
6666 {
6667     IHTMLElementCollection *col;
6668     IHTMLTxtRange *range;
6669     HRESULT hres;
6670
6671     static const elem_type_t all_types[] = {
6672         ET_HTML,
6673         ET_HEAD,
6674         ET_TITLE,
6675         ET_BODY,
6676         ET_BR,
6677         ET_A,
6678     };
6679
6680     static const elem_type_t indent_types[] = {
6681         ET_HTML,
6682         ET_HEAD,
6683         ET_TITLE,
6684         ET_BODY,
6685         ET_BLOCKQUOTE,
6686         ET_P,
6687         ET_BR,
6688         ET_A,
6689     };
6690
6691     hres = IHTMLDocument2_get_all(doc, &col);
6692     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6693     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6694     IHTMLElementCollection_Release(col);
6695
6696     range = test_create_body_range(doc);
6697     test_exec((IUnknown*)range, &CGID_MSHTML, IDM_INDENT, NULL, NULL);
6698     IHTMLTxtRange_Release(range);
6699
6700     hres = IHTMLDocument2_get_all(doc, &col);
6701     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6702     test_elem_collection((IUnknown*)col, indent_types, sizeof(indent_types)/sizeof(indent_types[0]));
6703     IHTMLElementCollection_Release(col);
6704 }
6705
6706 static void test_cond_comment(IHTMLDocument2 *doc)
6707 {
6708     IHTMLElementCollection *col;
6709     HRESULT hres;
6710
6711     static const elem_type_t all_types[] = {
6712         ET_HTML,
6713         ET_HEAD,
6714         ET_TITLE,
6715         ET_BODY,
6716         ET_BR
6717     };
6718
6719     hres = IHTMLDocument2_get_all(doc, &col);
6720     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6721     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6722     IHTMLElementCollection_Release(col);
6723 }
6724
6725 static void test_frame(IDispatch *disp, const char *exp_id)
6726 {
6727     IHTMLWindow2 *frame2, *parent, *top;
6728     IHTMLDocument2 *parent_doc, *top_doc;
6729     IHTMLWindow4 *frame;
6730     IHTMLFrameBase *frame_elem;
6731     HRESULT hres;
6732
6733     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame);
6734     ok(hres == S_OK, "Could not get IHTMLWindow4 interface: 0x%08x\n", hres);
6735     if(FAILED(hres))
6736         return;
6737
6738     hres = IHTMLWindow4_get_frameElement(frame, &frame_elem);
6739     ok(hres == S_OK, "IHTMLWindow4_get_frameElement failed: 0x%08x\n", hres);
6740     IHTMLWindow4_Release(frame);
6741     if(FAILED(hres))
6742         return;
6743
6744     test_elem_type((IUnknown*)frame_elem, ET_FRAME);
6745     test_frame_doc((IUnknown*)frame_elem, FALSE);
6746     test_elem_id((IUnknown*)frame_elem, exp_id);
6747     IHTMLFrameBase_Release(frame_elem);
6748
6749     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow2, (void**)&frame2);
6750     ok(hres == S_OK, "Could not get IHTMLWindow2 interface: 0x%08x\n", hres);
6751     if(FAILED(hres))
6752         return;
6753
6754     hres = IHTMLWindow2_get_parent(frame2, &parent);
6755     ok(hres == S_OK, "IHTMLWindow2_get_parent failed: 0x%08x\n", hres);
6756     if(FAILED(hres)){
6757         IHTMLWindow2_Release(frame2);
6758         return;
6759     }
6760
6761     hres = IHTMLWindow2_get_document(parent, &parent_doc);
6762     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
6763     IHTMLWindow2_Release(parent);
6764     if(FAILED(hres)){
6765         IHTMLWindow2_Release(frame2);
6766         return;
6767     }
6768
6769     test_doc_title(parent_doc, "frameset test");
6770     IHTMLDocument2_Release(parent_doc);
6771
6772     /* test get_top */
6773     hres = IHTMLWindow2_get_top(frame2, &top);
6774     ok(hres == S_OK, "IHTMLWindow2_get_top failed: 0x%08x\n", hres);
6775     IHTMLWindow2_Release(frame2);
6776     if(FAILED(hres))
6777         return;
6778
6779     hres = IHTMLWindow2_get_document(top, &top_doc);
6780     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
6781     IHTMLWindow2_Release(top);
6782     if(FAILED(hres))
6783         return;
6784
6785     test_doc_title(top_doc, "frameset test");
6786     IHTMLDocument2_Release(top_doc);
6787 }
6788
6789 static void test_frames_collection(IHTMLFramesCollection2 *frames, const char *frid)
6790 {
6791     VARIANT index_var, result_var;
6792     LONG length;
6793     HRESULT hres;
6794
6795     /* test result length */
6796     hres = IHTMLFramesCollection2_get_length(frames, &length);
6797     ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres);
6798     ok(length == 3, "IHTMLFramesCollection2_get_length should have been 3, was: %d\n", length);
6799
6800     /* test first frame */
6801     V_VT(&index_var) = VT_I4;
6802     V_I4(&index_var) = 0;
6803     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6804     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
6805     if(SUCCEEDED(hres)) {
6806         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6807         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
6808     }
6809     VariantClear(&result_var);
6810
6811     /* test second frame */
6812     V_I4(&index_var) = 1;
6813     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6814     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
6815     if(SUCCEEDED(hres)) {
6816         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6817         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
6818     }
6819     VariantClear(&result_var);
6820
6821     /* fail on next frame */
6822     V_I4(&index_var) = 3;
6823     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6824     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have"
6825            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
6826     VariantClear(&result_var);
6827
6828     /* string argument (element id lookup) */
6829     V_VT(&index_var) = VT_BSTR;
6830     V_BSTR(&index_var) = a2bstr(frid);
6831     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6832     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
6833     if(SUCCEEDED(hres)) {
6834         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6835         test_frame(V_DISPATCH(&result_var), frid);
6836     }
6837     VariantClear(&result_var);
6838     VariantClear(&index_var);
6839
6840     /* invalid argument */
6841     V_VT(&index_var) = VT_BOOL;
6842     V_BOOL(&index_var) = VARIANT_TRUE;
6843     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6844     ok(hres == E_INVALIDARG, "IHTMLFramesCollection2_item should have"
6845            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
6846     VariantClear(&result_var);
6847 }
6848
6849 static void test_frameset(IHTMLDocument2 *doc)
6850 {
6851     IHTMLWindow2 *window;
6852     IHTMLFramesCollection2 *frames;
6853     IHTMLElement *elem;
6854     HRESULT hres;
6855
6856     window = get_doc_window(doc);
6857
6858     /* test using IHTMLFramesCollection object */
6859
6860     hres = IHTMLWindow2_get_frames(window, &frames);
6861     ok(hres == S_OK, "IHTMLWindow2_get_frames failed: 0x%08x\n", hres);
6862     if(FAILED(hres))
6863         return;
6864
6865     test_frames_collection(frames, "fr1");
6866     IHTMLFramesCollection2_Release(frames);
6867
6868     hres = IHTMLDocument2_get_frames(doc, &frames);
6869     ok(hres == S_OK, "IHTMLDocument2_get_frames failed: 0x%08x\n", hres);
6870     if(FAILED(hres))
6871         return;
6872
6873     test_frames_collection(frames, "fr1");
6874     IHTMLFramesCollection2_Release(frames);
6875
6876     /* test using IHTMLWindow2 inheritance */
6877     test_frames_collection((IHTMLFramesCollection2*)window, "fr2");
6878
6879     /* getElementById with node name attributes */
6880     elem = get_doc_elem_by_id(doc, "nm1");
6881     test_elem_id((IUnknown*)elem, "fr1");
6882
6883     test_framebase((IUnknown*)elem);
6884     test_framebase_name(elem, "nm1");
6885     test_framebase_put_name(elem, "frame name");
6886     test_framebase_put_name(elem, NULL);
6887     test_framebase_put_name(elem, "nm1");
6888     IHTMLElement_Release(elem);
6889
6890     /* get_name with no name attr */
6891     elem = get_doc_elem_by_id(doc, "fr3");
6892     test_framebase_name(elem, NULL);
6893     test_framebase_put_name(elem, "frame name");
6894     test_framebase_put_name(elem, NULL);
6895     IHTMLElement_Release(elem);
6896
6897     IHTMLWindow2_Release(window);
6898 }
6899
6900 static IHTMLDocument2 *create_docfrag(IHTMLDocument2 *doc)
6901 {
6902     IHTMLDocument2 *frag;
6903     IHTMLDocument3 *doc3;
6904     HRESULT hres;
6905
6906     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
6907     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
6908
6909     hres = IHTMLDocument3_createDocumentFragment(doc3, &frag);
6910     IHTMLDocument3_Release(doc3);
6911     ok(hres == S_OK, "createDocumentFragment failed: %08x\n", hres);
6912     ok(frag != NULL, "frag == NULL\n");
6913
6914     return frag;
6915 }
6916
6917 static void test_docfrag(IHTMLDocument2 *doc)
6918 {
6919     IHTMLDocument2 *frag, *owner_doc, *doc_node;
6920     IHTMLElement *div, *body, *br;
6921     IHTMLElementCollection *col;
6922     IHTMLLocation *location;
6923     HRESULT hres;
6924
6925     static const elem_type_t all_types[] = {
6926         ET_HTML,
6927         ET_HEAD,
6928         ET_TITLE,
6929         ET_BODY,
6930         ET_DIV,
6931         ET_BR
6932     };
6933
6934     frag = create_docfrag(doc);
6935
6936     test_disp((IUnknown*)frag, &DIID_DispHTMLDocument, "[object]");
6937
6938     body = (void*)0xdeadbeef;
6939     hres = IHTMLDocument2_get_body(frag, &body);
6940     ok(hres == S_OK, "get_body failed: %08x\n", hres);
6941     ok(!body, "body != NULL\n");
6942
6943     location = (void*)0xdeadbeef;
6944     hres = IHTMLDocument2_get_location(frag, &location);
6945     ok(hres == E_UNEXPECTED, "get_location failed: %08x\n", hres);
6946     ok(location == (void*)0xdeadbeef, "location changed\n");
6947
6948     br = test_create_elem(doc, "BR");
6949     test_node_append_child((IUnknown*)frag, (IUnknown*)br);
6950     IHTMLElement_Release(br);
6951
6952     div = get_elem_by_id(doc, "divid", TRUE);
6953     test_node_append_child((IUnknown*)div, (IUnknown*)frag);
6954     IHTMLElement_Release(div);
6955
6956     hres = IHTMLDocument2_get_all(doc, &col);
6957     ok(hres == S_OK, "get_all failed: %08x\n", hres);
6958     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
6959     IHTMLElementCollection_Release(col);
6960
6961     div = test_create_elem(frag, "div");
6962     owner_doc = get_owner_doc((IUnknown*)div);
6963     doc_node = get_doc_node(doc);
6964     ok(iface_cmp((IUnknown*)owner_doc, (IUnknown*)doc_node), "owner_doc != doc_node\n");
6965     IHTMLDocument2_Release(doc_node);
6966     IHTMLDocument2_Release(owner_doc);
6967     IHTMLElement_Release(div);
6968
6969     IHTMLDocument2_Release(frag);
6970 }
6971
6972 static IHTMLDocument2 *notif_doc;
6973 static BOOL doc_complete;
6974
6975 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
6976         REFIID riid, void**ppv)
6977 {
6978     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
6979         *ppv = iface;
6980         return S_OK;
6981     }
6982
6983     ok(0, "unexpected call\n");
6984     return E_NOINTERFACE;
6985 }
6986
6987 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
6988 {
6989     return 2;
6990 }
6991
6992 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
6993 {
6994     return 1;
6995 }
6996
6997 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
6998 {
6999     if(dispID == DISPID_READYSTATE){
7000         BSTR state;
7001         HRESULT hres;
7002
7003         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
7004         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
7005
7006         if(!strcmp_wa(state, "complete"))
7007             doc_complete = TRUE;
7008
7009         SysFreeString(state);
7010     }
7011
7012     return S_OK;
7013 }
7014
7015 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
7016 {
7017     ok(0, "unexpected call\n");
7018     return E_NOTIMPL;
7019 }
7020
7021 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
7022     PropertyNotifySink_QueryInterface,
7023     PropertyNotifySink_AddRef,
7024     PropertyNotifySink_Release,
7025     PropertyNotifySink_OnChanged,
7026     PropertyNotifySink_OnRequestEdit
7027 };
7028
7029 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
7030
7031 static IHTMLDocument2 *create_doc_with_string(const char *str)
7032 {
7033     IPersistStreamInit *init;
7034     IStream *stream;
7035     IHTMLDocument2 *doc;
7036     HGLOBAL mem;
7037     SIZE_T len;
7038
7039     notif_doc = doc = create_document();
7040     if(!doc)
7041         return NULL;
7042
7043     doc_complete = FALSE;
7044     len = strlen(str);
7045     mem = GlobalAlloc(0, len);
7046     memcpy(mem, str, len);
7047     CreateStreamOnHGlobal(mem, TRUE, &stream);
7048
7049     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
7050
7051     IPersistStreamInit_Load(init, stream);
7052     IPersistStreamInit_Release(init);
7053     IStream_Release(stream);
7054
7055     return doc;
7056 }
7057
7058 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
7059 {
7060     IConnectionPointContainer *container;
7061     IConnectionPoint *cp;
7062     DWORD cookie;
7063     HRESULT hres;
7064
7065     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
7066     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
7067
7068     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
7069     IConnectionPointContainer_Release(container);
7070     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
7071
7072     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
7073     IConnectionPoint_Release(cp);
7074     ok(hres == S_OK, "Advise failed: %08x\n", hres);
7075 }
7076
7077 typedef void (*domtest_t)(IHTMLDocument2*);
7078
7079 static void run_domtest(const char *str, domtest_t test)
7080 {
7081     IHTMLDocument2 *doc;
7082     ULONG ref;
7083     MSG msg;
7084
7085     doc = create_doc_with_string(str);
7086     if(!doc)
7087         return;
7088
7089     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
7090
7091     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
7092         TranslateMessage(&msg);
7093         DispatchMessage(&msg);
7094     }
7095
7096     test(doc);
7097
7098     ref = IHTMLDocument2_Release(doc);
7099     ok(!ref || broken(ref == 1), /* Vista */
7100        "ref = %d\n", ref);
7101 }
7102
7103 START_TEST(dom)
7104 {
7105     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
7106     pLCIDToLocaleName = (void*)GetProcAddress(hkernel32, "LCIDToLocaleName");
7107     pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
7108
7109     CoInitialize(NULL);
7110
7111     run_domtest(doc_str1, test_doc_elem);
7112     run_domtest(doc_str1, test_get_set_attr);
7113     run_domtest(range_test_str, test_txtrange);
7114     run_domtest(range_test2_str, test_txtrange2);
7115     if (winetest_interactive || ! is_ie_hardened()) {
7116         run_domtest(elem_test_str, test_elems);
7117         run_domtest(elem_test2_str, test_elems2);
7118         run_domtest(noscript_str, test_noscript);
7119     }else {
7120         skip("IE running in Enhanced Security Configuration\n");
7121     }
7122     run_domtest(doc_blank, test_create_elems);
7123     run_domtest(doc_blank, test_defaults);
7124     run_domtest(doc_blank, test_null_write);
7125     run_domtest(emptydiv_str, test_create_stylesheet);
7126     run_domtest(indent_test_str, test_indent);
7127     run_domtest(cond_comment_str, test_cond_comment);
7128     run_domtest(frameset_str, test_frameset);
7129     run_domtest(emptydiv_str, test_docfrag);
7130     run_domtest(doc_blank, test_replacechild_elems);
7131     run_domtest(doctype_str, test_doctype);
7132
7133     CoUninitialize();
7134 }