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