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