2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
21 #include <wine/test.h>
32 #include "ieautomation.h"
34 #define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37 #define SET_EXPECT(func) \
38 expect_ ## func = TRUE
40 #define CHECK_EXPECT2(func) \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 called_ ## func = TRUE; \
46 #define CHECK_EXPECT(func) \
48 CHECK_EXPECT2(func); \
49 expect_ ## func = FALSE; \
52 #define CHECK_CALLED(func) \
54 ok(called_ ## func, "expected " #func "\n"); \
55 expect_ ## func = called_ ## func = FALSE; \
58 DEFINE_EXPECT(Invoke_BEFORENAVIGATE2
);
59 DEFINE_EXPECT(Invoke_NAVIGATECOMPLETE2
);
60 DEFINE_EXPECT(Invoke_NAVIGATEERROR
);
61 DEFINE_EXPECT(Invoke_DOCUMENTCOMPLETE
);
63 static BOOL navigate_complete
, navigation_timed_out
;
64 static const WCHAR
*navigate_url
;
66 static BSTR
get_window_url(IDispatch
*webbrowser
)
68 IHTMLPrivateWindow
*priv_window
;
69 IHTMLLocation
*location
;
76 hres
= IDispatch_QueryInterface(webbrowser
, &IID_IServiceProvider
, (void**)&sp
);
77 ok(hres
== S_OK
, "QueryInterface(IServiceProvider) failed: %08lx\n", hres
);
79 hres
= IServiceProvider_QueryService(sp
, &SID_SHTMLWindow
, &IID_IHTMLWindow2
, (void**)&window
);
80 ok(hres
== S_OK
, "Could not get SHTMLWindow service: %08lx\n", hres
);
81 ok(window
!= NULL
, "window = NULL\n");
82 IServiceProvider_Release(sp
);
84 hres
= IHTMLWindow2_QueryInterface(window
, &IID_IHTMLPrivateWindow
, (void**)&priv_window
);
85 ok(hres
== E_NOINTERFACE
, "QueryInterface(IID_IHTMLPrivateWindow) returned: %08lx\n", hres
);
87 hres
= IHTMLWindow2_get_document(window
, &doc
);
88 ok(hres
== S_OK
, "get_document failed: %08lx\n", hres
);
89 ok(doc
!= NULL
, "doc = NULL\n");
90 IHTMLWindow2_Release(window
);
92 hres
= IHTMLDocument2_get_parentWindow(doc
, &window
);
93 ok(hres
== S_OK
, "get_parentWindow failed: %08lx\n", hres
);
94 ok(window
!= NULL
, "window = NULL\n");
95 IHTMLDocument2_Release(doc
);
97 hres
= IHTMLWindow2_get_location(window
, &location
);
98 ok(hres
== S_OK
, "get_location failed: %08lx\n", hres
);
99 ok(location
!= NULL
, "location = NULL\n");
100 IHTMLWindow2_Release(window
);
102 hres
= IHTMLLocation_get_href(location
, &url
);
103 ok(hres
== S_OK
, "get_href failed: %08lx\n", hres
);
104 ok(url
!= NULL
, "url = NULL\n");
105 IHTMLLocation_Release(location
);
110 #define test_url(a) _test_url(__LINE__,a)
111 static void _test_url(unsigned line
, const WCHAR
*url
)
113 /* If error page, it actually returns the error page's resource URL, followed by #, followed by the original URL.
114 Since the error page's location varies on native, and depends on the error itself, just check for res:// here. */
115 if(called_Invoke_NAVIGATEERROR
) {
116 ok_(__FILE__
,line
)(!wcsncmp(url
, L
"res://", ARRAY_SIZE(L
"res://")-1), "url is not a local resource: %s\n", wine_dbgstr_w(url
));
117 url
= wcschr(url
, '#');
118 ok_(__FILE__
,line
)(url
!= NULL
, "url has no fragment: %s\n", wine_dbgstr_w(url
));
119 ok_(__FILE__
,line
)(!wcscmp(url
+ 1, navigate_url
), "url after fragment = %s\n", wine_dbgstr_w(url
+ 1));
121 ok_(__FILE__
,line
)(!wcscmp(url
, navigate_url
), "url = %s\n", wine_dbgstr_w(url
));
125 static HRESULT WINAPI
Dispatch_QueryInterface(IDispatch
*iface
, REFIID riid
, void **ppv
)
127 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IDispatch
, riid
)) {
133 return E_NOINTERFACE
;
136 static ULONG WINAPI
Dispatch_AddRef(IDispatch
*iface
)
141 static ULONG WINAPI
Dispatch_Release(IDispatch
*iface
)
146 static HRESULT WINAPI
Dispatch_GetTypeInfoCount(IDispatch
*iface
, UINT
*pctinfo
)
148 ok(0, "unexpected call\n");
152 static HRESULT WINAPI
Dispatch_GetTypeInfo(IDispatch
*iface
, UINT iTInfo
, LCID lcid
,
155 ok(0, "unexpected call\n");
159 static HRESULT WINAPI
Dispatch_GetIDsOfNames(IDispatch
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
160 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
162 ok(0, "unexpected call\n");
166 static HRESULT WINAPI
Dispatch_Invoke(IDispatch
*iface
, DISPID dispIdMember
, REFIID riid
,
167 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
168 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
173 switch(dispIdMember
) {
174 case DISPID_BEFORENAVIGATE2
:
175 CHECK_EXPECT(Invoke_BEFORENAVIGATE2
);
177 arg
= pDispParams
->rgvarg
+ 5;
178 ok(V_VT(arg
) == (VT_BYREF
| VT_VARIANT
), "VT = %d\n", V_VT(arg
));
179 ok(V_VT(V_VARIANTREF(arg
)) == VT_BSTR
, "VT = %d\n", V_VT(V_VARIANTREF(arg
)));
181 test_url(V_BSTR(V_VARIANTREF(arg
)));
183 case DISPID_NAVIGATECOMPLETE2
:
184 CHECK_EXPECT(Invoke_NAVIGATECOMPLETE2
);
186 arg
= pDispParams
->rgvarg
;
187 ok(V_VT(arg
) == (VT_BYREF
| VT_VARIANT
), "VT = %d\n", V_VT(arg
));
188 ok(V_VT(V_VARIANTREF(arg
)) == VT_BSTR
, "VT = %d\n", V_VT(V_VARIANTREF(arg
)));
189 ok(!wcscmp(V_BSTR(V_VARIANTREF(arg
)), navigate_url
), "url = %s\n", wine_dbgstr_w(V_BSTR(V_VARIANTREF(arg
))));
191 arg
= pDispParams
->rgvarg
+ 1;
192 ok(V_VT(arg
) == VT_DISPATCH
, "VT = %d\n", V_VT(arg
));
193 ok(V_DISPATCH(arg
) != NULL
, "V_DISPATCH = NULL\n");
194 url
= get_window_url(V_DISPATCH(arg
));
198 case DISPID_NAVIGATEERROR
:
199 CHECK_EXPECT(Invoke_NAVIGATEERROR
);
200 ok(!called_Invoke_NAVIGATECOMPLETE2
, "NAVIGATECOMPLETE2 called before NAVIGATEERROR\n");
202 arg
= pDispParams
->rgvarg
;
203 ok(V_VT(arg
) == (VT_BYREF
| VT_BOOL
), "VT = %d\n", V_VT(arg
));
204 ok(*V_BOOLREF(arg
) == VARIANT_FALSE
, "cancel = %#x\n", *V_BOOLREF(arg
));
206 arg
= pDispParams
->rgvarg
+ 3;
207 ok(V_VT(arg
) == (VT_BYREF
| VT_VARIANT
), "VT = %d\n", V_VT(arg
));
208 ok(V_VT(V_VARIANTREF(arg
)) == VT_BSTR
, "VT = %d\n", V_VT(V_VARIANTREF(arg
)));
209 ok(!wcscmp(V_BSTR(V_VARIANTREF(arg
)), navigate_url
), "url = %s\n", wine_dbgstr_w(V_BSTR(V_VARIANTREF(arg
))));
211 case DISPID_DOCUMENTCOMPLETE
:
212 CHECK_EXPECT(Invoke_DOCUMENTCOMPLETE
);
213 navigate_complete
= TRUE
;
215 arg
= pDispParams
->rgvarg
;
216 ok(V_VT(arg
) == (VT_BYREF
| VT_VARIANT
), "VT = %d\n", V_VT(arg
));
217 ok(V_VT(V_VARIANTREF(arg
)) == VT_BSTR
, "VT = %d\n", V_VT(V_VARIANTREF(arg
)));
218 ok(!wcscmp(V_BSTR(V_VARIANTREF(arg
)), navigate_url
), "url = %s\n", wine_dbgstr_w(V_BSTR(V_VARIANTREF(arg
))));
220 arg
= pDispParams
->rgvarg
+ 1;
221 ok(V_VT(arg
) == VT_DISPATCH
, "VT = %d\n", V_VT(arg
));
222 ok(V_DISPATCH(arg
) != NULL
, "V_DISPATCH = NULL\n");
223 url
= get_window_url(V_DISPATCH(arg
));
232 static IDispatchVtbl DispatchVtbl
= {
233 Dispatch_QueryInterface
,
236 Dispatch_GetTypeInfoCount
,
237 Dispatch_GetTypeInfo
,
238 Dispatch_GetIDsOfNames
,
242 static IDispatch Dispatch
= { &DispatchVtbl
};
244 static void advise_cp(IUnknown
*unk
, BOOL init
)
246 IConnectionPointContainer
*container
;
247 IConnectionPoint
*point
;
250 static DWORD cookie
= 100;
252 hres
= IUnknown_QueryInterface(unk
, &IID_IConnectionPointContainer
, (void**)&container
);
253 ok(hres
== S_OK
, "QueryInterface(IID_IConnectionPointContainer) failed: %08lx\n", hres
);
257 hres
= IConnectionPointContainer_FindConnectionPoint(container
, &DIID_DWebBrowserEvents2
, &point
);
258 IConnectionPointContainer_Release(container
);
259 if(!navigation_timed_out
)
260 ok(hres
== S_OK
, "FindConnectionPoint failed: %08lx\n", hres
);
265 hres
= IConnectionPoint_Advise(point
, (IUnknown
*)&Dispatch
, &cookie
);
266 ok(hres
== S_OK
, "Advise failed: %08lx\n", hres
);
268 hres
= IConnectionPoint_Unadvise(point
, cookie
);
269 ok(hres
== S_OK
, "Unadvise failed: %08lx\n", hres
);
272 IConnectionPoint_Release(point
);
276 static void test_visible(IWebBrowser2
*wb
)
282 hres
= IWebBrowser2_get_Visible(wb
, &b
);
283 ok(hres
== S_OK
, "get_Visible failed: %08lx\n", hres
);
284 ok(b
== VARIANT_FALSE
, "Visible = %x\n", b
);
286 hres
= IWebBrowser2_put_Visible(wb
, VARIANT_TRUE
);
287 ok(hres
== S_OK
, "put_Visible failed: %08lx\n", hres
);
290 hres
= IWebBrowser2_get_Visible(wb
, &b
);
291 ok(hres
== S_OK
, "get_Visible failed: %08lx\n", hres
);
292 ok(b
== VARIANT_TRUE
, "Visible = %x\n", b
);
294 hres
= IWebBrowser2_put_Visible(wb
, VARIANT_FALSE
);
295 ok(hres
== S_OK
, "put_Visible failed: %08lx\n", hres
);
298 static void test_html_window(IWebBrowser2
*wb
)
300 IHTMLWindow2
*html_window
;
301 IServiceProvider
*sp
;
304 hres
= IWebBrowser2_QueryInterface(wb
, &IID_IServiceProvider
, (void**)&sp
);
305 ok(hres
== S_OK
, "Could not get IServiceProvider iface: %08lx\n", hres
);
307 hres
= IServiceProvider_QueryService(sp
, &SID_SHTMLWindow
, &IID_IHTMLWindow2
, (void**)&html_window
);
308 IServiceProvider_Release(sp
);
309 ok(hres
== S_OK
, "Could not get SHTMLWindow service: %08lx\n", hres
);
311 IHTMLWindow2_Release(html_window
);
314 static void test_window(IWebBrowser2
*wb
)
316 SHANDLE_PTR handle
= 0;
321 hres
= IWebBrowser2_get_HWND(wb
, &handle
);
322 ok(hres
== S_OK
, "get_HWND failed: %08lx\n", hres
);
323 ok(handle
, "handle == 0\n");
326 GetClassNameA(hwnd
, buf
, sizeof(buf
));
327 ok(!strcmp(buf
, "IEFrame"), "Unexpected class name %s\n", buf
);
330 static void CALLBACK
navigate_timeout(HWND hwnd
, UINT msg
, UINT_PTR timer
, DWORD time
)
332 win_skip("Navigation timed out, skipping tests...\n");
333 called_Invoke_BEFORENAVIGATE2
= TRUE
;
334 called_Invoke_NAVIGATECOMPLETE2
= TRUE
;
335 called_Invoke_DOCUMENTCOMPLETE
= TRUE
;
336 if(expect_Invoke_NAVIGATEERROR
)
337 CHECK_EXPECT(Invoke_NAVIGATEERROR
);
338 navigation_timed_out
= TRUE
;
339 navigate_complete
= TRUE
;
342 static void test_navigate(IWebBrowser2
*wb
, const WCHAR
*url
, DWORD timeout
)
344 VARIANT urlv
, emptyv
;
349 SET_EXPECT(Invoke_BEFORENAVIGATE2
);
350 SET_EXPECT(Invoke_NAVIGATECOMPLETE2
);
351 SET_EXPECT(Invoke_DOCUMENTCOMPLETE
);
352 navigation_timed_out
= FALSE
;
353 navigate_complete
= FALSE
;
356 V_VT(&urlv
) = VT_BSTR
;
357 V_BSTR(&urlv
) = SysAllocString(url
);
358 V_VT(&emptyv
) = VT_EMPTY
;
359 hres
= IWebBrowser2_Navigate2(wb
, &urlv
, &emptyv
, &emptyv
, &emptyv
, &emptyv
);
360 ok(hres
== S_OK
, "Navigate2 failed: %08lx\n", hres
);
361 SysFreeString(V_BSTR(&urlv
));
364 timer
= SetTimer(NULL
, 0, timeout
, navigate_timeout
);
366 while(!navigate_complete
&& GetMessageW(&msg
, NULL
, 0, 0)) {
367 TranslateMessage(&msg
);
368 DispatchMessageW(&msg
);
372 KillTimer(NULL
, timer
);
374 CHECK_CALLED(Invoke_BEFORENAVIGATE2
);
375 CHECK_CALLED(Invoke_NAVIGATECOMPLETE2
);
376 CHECK_CALLED(Invoke_DOCUMENTCOMPLETE
);
379 static void test_busy(IWebBrowser2
*wb
)
385 hres
= IWebBrowser2_get_Busy(wb
, &b
);
386 ok(hres
== S_OK
, "get_Busy failed: %08lx\n", hres
);
387 ok(b
== VARIANT_FALSE
, "Busy = %x\n", b
);
390 static void test_InternetExplorer(void)
397 hres
= CoCreateInstance(&CLSID_InternetExplorer
, NULL
, CLSCTX_SERVER
,
398 &IID_IUnknown
, (void**)&unk
);
399 ok(hres
== S_OK
, "Could not create InternetExplorer instance: %08lx\n", hres
);
404 hres
= IUnknown_QueryInterface(unk
, &IID_IWebBrowser2
, (void**)&wb
);
405 ok(hres
== S_OK
, "Could not get IWebBrowser2 interface: %08lx\n", hres
);
407 IUnknown_Release(unk
);
411 advise_cp(unk
, TRUE
);
415 test_html_window(wb
);
417 test_navigate(wb
, L
"http://test.winehq.org/tests/hello.html", 0);
419 SET_EXPECT(Invoke_NAVIGATEERROR
);
420 test_navigate(wb
, L
"http://0.0.0.0:1234/#frag?query=foo&wine=bar", 6000);
421 CHECK_CALLED(Invoke_NAVIGATEERROR
);
423 advise_cp(unk
, FALSE
);
425 IWebBrowser2_Release(wb
);
426 ref
= IUnknown_Release(unk
);
427 ok(!ref
, "object not destroyed, ref=%lu\n", ref
);
430 static void test_InternetExplorerManager(void)
436 hres
= CoCreateInstance(&CLSID_InternetExplorerManager
, NULL
, CLSCTX_LOCAL_SERVER
,
437 &IID_IInternetExplorerManager
, (void**)&unk
);
438 ok(hres
== S_OK
|| broken(hres
== REGDB_E_CLASSNOTREG
), "Could not create InternetExplorerManager instance: %08lx\n", hres
);
442 win_skip("InternetExplorerManager not available\n");
446 ref
= IUnknown_Release(unk
);
447 ok(!ref
, "object not destroyed, ref=%lu\n", ref
);
454 test_InternetExplorerManager();
456 test_InternetExplorer();