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